简体   繁体   English

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

[英]Force to do flush to get new Primary key ID to store EmbeddedId

We are using JPA and we are using EmbeddedId in one of the Entity . 我们正在使用JPA并且在Entity之一中使用了EmbeddedId

Tables are as bellow : 表格如下:

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


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

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

Entity for role table is: 角色表的实体为:

@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;

.......
}

Entity for rightrole table is: rightrole表的实体为:

    @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;

   .....

}

My problem is whenever I want to create new role with rights then first I have to store(persist) role object and then I have to do flush to get newly generated id for role. 我的问题是,每当我要创建具有rightsrole ,首先我必须store(persist) role对象,然后必须进行flush以获取角色的新生成的id then and then i can put it in rightrole entity's object. 然后,我可以将它放在rightrole实体的对象中。

Is there any way by that i can set rightrole list in role object and persist it in one go. 有什么办法可以在角色对象中设置rightrole角色列表并将其持久保存。

This flush casing us performance bottle neck because for bulk insert we have to persist single single object. 这种齐平的外壳使我们成为性能瓶颈,因为要进行大容量插入,我们必须保留单个单个对象。

we are using Auto Generated primary key. 我们正在使用Auto Generated主键。

JPA 2.0 allows derived IDs, an expanded to support this better by adding @MapsId . JPA 2.0允许派生ID,通过添加@MapsId可以更好地支持派生ID。 Keeping everything else the same but using: 保持其他所有不变,但使用:

@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;

    ......
 }

This will tell JPA that the value within the roleID and rightID attributes in your PK class are controlled by the relationship mapping, and it will set it after synchronizing to the database with the primary key value from the reference. 这将告诉JPA,您的PK类中的roleIDrightID属性中的值由关系映射控制,并且它将与参考中的主键值同步到数据库后进行设置。 You just need to be sure you set the relationship before calling persist, as it doesn't have a primary key otherwise. 您只需要确保在调用persist之前就设置了关系,否则它将没有主键。

This works even if the referenced object is also composite. 即使引用的对象也是复合对象,此方法也有效。 Something that needs to reference RightRole would use RightRolePK though instead of a Long value: 需要引用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 also allows marking the right and role mappings with the @ID annotation, allowing you to remove the rightRolePK embeddedId from within the object, and use it as a primary key class instead. JPA还允许使用@ID批注标记right映射和role映射,从而允许您从对象内部删除rightRolePK embeddedId ,并将其用作主键类。

Using a @ManyToMany annotation you can define your entity like this: 使用@ManyToMany批注,您可以像这样定义您的实体:

Role: 角色:

 @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;

    }

You have to write @ManyToMany(cascade = {CascadeType.PERSIST}) in inverseJoinColumns otherwise your parent data will get deleted if child get deleted. 您必须在inverseJoinColumns编写@ManyToMany(cascade = {CascadeType.PERSIST}) ,否则如果删除子@ManyToMany(cascade = {CascadeType.PERSIST}) ,则父级数据也将被删除。

Right: 对:

@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;

}

you can then simply: 您可以然后简单地:

    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);

and persist 并坚持

the @JoinTable annotation will take care of inserting in the rightrole table even without an entity (as long as that table have only the id columns of role and right) so you'll get something like this in db @JoinTable批注将负责在没有实体的情况下插入到rightrole表中(只要该表仅具有role和right的id列),因此您将在db中获得类似的内容

Role : 角色:

id name     etc
1  roleName etc

Right: 对:

id name       etc
1  rightName1 etc
2  rightName2 etc

rightrole: 右角色:

roleId rightID
1      1
1      2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM