2017-06-06 69 views
0

我们使用JPA,并且我们在Entity之一中使用EmbeddedId强制刷新以获取新的主键ID以存储EmbeddedId

表有波纹管:

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


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

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

实体的角色表是:

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

....... 
} 

实体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; 

    ..... 

} 

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

有没有什么办法,我可以在角色对象中设置rightrole列表,并一次性保存它。

这个冲洗套管我们的性能瓶颈因为对于批量插入我们必须坚持单个单一的对象。

我们正在使用Auto Generated主键。

+0

对角色使用不同的策略?像一个UUID。 RightRole有一个自动生成的ID,而不是你用混合身份识别这个黑客混乱? –

+0

我们有大约35个表格,我们正在使用这种复合标识,因此改变这种方式需要在我们现有的应用程序中进行大量的代码更改。 –

+0

只是一个建议,如果你实际上可以简化它:使用@joinTable注解来获得manyToMany关系,就像没有额外的列,除了右边的表中的Ids。 这将使这件事情容易,因为创建两个对象,加权利的作用rightList,坚持 – Zeromus

回答

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,在你的PK类roleIDrightID属性中的值是由关系映射控制,它将与同步到数据库后设置参考的主键值。您只需确保在调用persist之前设置关系,否则就没有主键。

这个工程即使引用的对象也是复合材料。一些需要参考RightRole将使用虽然代替长值RightRolePK:

@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还允许标志着rightrole映射与@ID注解,让您从对象中删除rightRolePK embeddedId和使用它将其作为主键类。

+0

我得到这个错误org.eclipse.persistence.mappings.DatabaseMapping.setAttributeValueInObject(DatabaseMapping.java:1637) at org.eclipse.persistence.internal.descriptors.PersistenceObjectAttributeAccessor.setAttributeValueInObject(PersistenceObjectAttributeAccessor.java:46) at org.eclipse.persistence.mappings.DatabaseMapping.setRealAttributeValueInObject(DatabaseMapping.java:1651) at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.updateDerivedIds(UnitOfWorkImpl.java:5461) at org.eclipse.persistence.internal。 sessions.UnitO fWorkImpl.registerNewObjectForPersist(UnitOfWor –

+0

解决这个问题,谢谢。 –

1

使用@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})否则你的父数据将被删除,如果孩子被删除。

右:

@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注解会照顾在rightrole表中插入的,即使没有实体(只要该表只有角色和权利的id列),所以你会得到像这样的db

作用:

id name  etc 
1 roleName etc 

右:

id name  etc 
1 rightName1 etc 
2 rightName2 etc 

rightrole:

roleId rightID 
1  1 
1  2 
+0

什么是'rightrole'实体? –

+0

如果您rightrole实体才被定义角色ID和rightId之间的联系,你不需要它 – Zeromus

+0

您解决方案仅在两个(父)列,但如果我有'rightrole'表的多个列的内容。 –