We are using JPA
and we are using EmbeddedId
in one of the Entity
.
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:
@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. then and then i can put it in rightrole
entity's object.
Is there any way by that i can set rightrole
list in role object and persist it in one go.
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.
JPA 2.0 allows derived IDs, an expanded to support this better by adding @MapsId. 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. You just need to be sure you set the relationship before calling persist, as it doesn't have a primary key otherwise.
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:
@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.