强制刷新以获取新的主键 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中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
,并将其用作一个主键 class 代替。
我们正在使用 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中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
,并将其用作一个主键 class 代替。