![](/img/trans.png)
[英]EclipseLink error: Entity class has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass
[英]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 |
+--------------------------------------+
角色表的实体为:
@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;
.....
}
我的问题是,每当我要创建具有rights
新role
,首先我必须store(persist)
role
对象,然后必须进行flush
以获取角色的新生成的id
。 然后,我可以将它放在rightrole
实体的对象中。
有什么办法可以在角色对象中设置rightrole
角色列表并将其持久保存。
这种齐平的外壳使我们成为性能瓶颈,因为要进行大容量插入,我们必须保留单个单个对象。
我们正在使用Auto Generated
主键。
JPA 2.0允许派生ID,通过添加@MapsId可以更好地支持派生ID。 保持其他所有不变,但使用:
@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类中的roleID
和rightID
属性中的值由关系映射控制,并且它将与参考中的主键值同步到数据库后进行设置。 您只需要确保在调用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
批注标记right
映射和role
映射,从而允许您从对象内部删除rightRolePK embeddedId
,并将其用作主键类。
使用@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})
,否则如果删除子@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表中(只要该表仅具有role和right的id列),因此您将在db中获得类似的内容
角色:
id name etc
1 roleName etc
对:
id name etc
1 rightName1 etc
2 rightName2 etc
右角色:
roleId rightID
1 1
1 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.