强制刷新以获取新的主键 ID 以存储 EmbeddedId

Force to do flush to get new Primary key ID to store EmbeddedId

我们正在使用 JPA,我们正在 Entity 之一中使用 EmbeddedId

表格如下:

Role:
+-----------------------------+
| roleId | name | discription |
+-----------------------------+


Rights:
+-----------------------------+
| rightId | name | discription|
+-----------------------------+

rightrole
+--------------------------------------+
| roleId | rightId | some other column |
+--------------------------------------+

角色 table 的实体是:

@Entity
@Table(name = "role")
public class Role {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(nullable = false)
    private Long roleID;


    @OneToMany(cascade = CascadeType.ALL, mappedBy = "role", fetch = FetchType.LAZY)
    private List<RightRole> rightRoleList;

.......
}

右角色 table 的实体是:

    @Entity
    @Table(name = "rightrole")
    public class RightRole extends BaseEntity<RightRolePK> {

        private static final long serialVersionUID = 1L;

        @EmbeddedId
        protected RightRolePK rightRolePK;


        @JoinColumn(name = "roleID", referencedColumnName = "roleID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Role role;

        @JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false)
        @ManyToOne(fetch = FetchType.LAZY)
        private Right right;

        ......
     }


    @Embeddable
    public class RightRolePK implements Serializable {
    private static final long serialVersionUID = 1L;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
      private long roleID;

      @Basic(optional = false)
      @NotNull
      @Column(nullable = false)
     private long rightID;

   .....

}

我的问题是每当我想用 rights 创建新的 role 时,首先我必须 store(persist) role 对象然后我必须做 flush 以获得新生成的 id 角色。然后我可以把它放在 rightrole 实体的对象中。

有什么方法可以在角色对象中设置 rightrole 列表并一次性持久化它。

这种齐平套管是我们的性能瓶颈,因为对于批量插入,我们必须保留单个对象。

我们正在使用 Auto Generated 主键。

使用@ManyToMany 注释,您可以像这样定义您的实体:

角色:

 @Entity
    @Table(name = "role")
    public class Role {

        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Basic(optional = false)
        @NotNull
        @Column(name = "ROLE_ID", nullable = false)
        private Long roleID;

        @JoinTable(name = "rightrole",
                joinColumns = {
                    @JoinColumn(name = "roleID", referencedColumnName = "ROLE_ID")},
                inverseJoinColumns = {
                    @JoinColumn(name = "rightID", referencedColumnName = "RIGHT_ID")})
        @ManyToMany
        private List<Right> rightList;

    }

您必须在 inverseJoinColumns 中写入 @ManyToMany(cascade = {CascadeType.PERSIST}) 否则如果 child 被删除,您的 parent 数据将被删除。

右:

@Entity
@Table(name = "right")
public class Right {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @NotNull
    @Column(name = "RIGHT_ID",nullable = false)
    private Long rightId;

}

然后您可以简单地:

    Role role = new  Role();
    List<Right> rightList = new ArrayList<>();
    Right right1 = new Right();
    Right right2 = new Right();
    rightList.add(right1);
    rightList.add(right2);
    role.setRightList(rightList);

并坚持

@JoinTable 注释将负责插入右角色 table 即使没有实体(只要 table 只有角色和权利的 id 列)所以你会在 db

中得到这样的东西

角色:

id name     etc
1  roleName etc

右:

id name       etc
1  rightName1 etc
2  rightName2 etc

右角色:

roleId rightID
1      1
1      2

JPA 2.0 允许派生 ID,并通过添加 @MapsId 进行扩展以更好地支持这一点。保持其他一切不变,但使用:

@Entity
@Table(name = "rightrole")
public class RightRole extends BaseEntity<RightRolePK> {

    private static final long serialVersionUID = 1L;

    @EmbeddedId
    protected RightRolePK rightRolePK;

    @MapsId("roleID")
    @JoinColumn(name = "roleID", referencedColumnName = "roleID")
    @ManyToOne(fetch = FetchType.LAZY)
    private Role role;

    @MapsId("rightID")
    @JoinColumn(name = "rightID", referencedColumnName = "rightID", insertable = false, updatable = false)
    @ManyToOne(fetch = FetchType.LAZY)
    private Right right;

    ......
 }

这将告诉JPA,你的PKclass中roleIDrightID属性中的值是由关系映射控制的,它会在同步到具有来自引用的主键值的数据库。您只需要确保在调用 persist 之前设置关系,否则它没有主键。

即使引用的对象也是复合的,这也有效。需要引用 RightRole 的内容将使用 RightRolePK 而不是 Long 值:

@Entity
@Table(name = "wrong_right_role")
public class WrongRightRole{
    @EmbeddedId
    WrongRightRoleId wrongRightRoleId;

    @MapsId("rightRoleID")
    @JoinColumns({
        @JoinColumn(name = "roleID", referencedColumnName = "roleID"),
        @JoinColumn(name = "rightID", referencedColumnName = "rightID")
    })
    RightRole rightRole;

}

@Embeddable
public class WrongRightRolePK implements Serializable {
private static final long serialVersionUID = 1L;

  private RightRoleID rightRoleID;
  .....
}

JPA 还允许使用 @ID 注释标记 rightrole 映射,允许您从对象中删除 rightRolePK embeddedId,并将其用作一个主键 class 代替。