I am using JPA 2.0 and hibernate. I have a User class and a Group class as follows:
public class User implements Serializable { @Id @Column(name="USER_ID") private String userId; @ManyToMany @JoinTable(name = "USER_GROUP", joinColumns = { @JoinColumn(name = "GROUP_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_ID") } ) private Set<Group> groupList; //get set methods } public class Group { @Id @Column(name="GROUP_ID") private String groupId; @ManyToMany(mappedBy="groupList") private Set<User> memberList; //get set methods }
And then, I create a user and group and then assign the user to the group.
What I want to have is when I delete the group, the group will be deleted (of course) and all the user-group relationship that the group has will be automatically deleted from the USER_GROUP join table but the user itself is not deleted from the USER table.
With the code I have above, only the row in the GROUP table will be deleted when I delete a group and the user will still have an entry to the deleted group in the USER_GROUP join table.
If I put cascade in the User class like this:
@ManyToMany(cascade=CascadeType.ALL) @JoinTable(name = "USER_GROUP", joinColumns = { @JoinColumn(name = "GROUP_ID") }, inverseJoinColumns = { @JoinColumn(name = "USER_ID") }) private Set<Group> groupList;
When I delete the group, the user will be deleted as well!
Is there any way to achieve what I want?
In JPA we use the @ManyToMany annotation to model many-to-many relationships. This type of relationship can be unidirectional or bidirectional: In a unidirectional relationship only one entity in the relationship points the other. In a bidirectional relationship both entities point to each other.
Hibernate. Hibernate Mapping. Learn to create and manage many-to-many relationships between entities in a hibernate/JPA-based applications using @ManyToMany annotation. A many-to-many association is made between two entities where one entity can be associated with multiple other instances of the other entity.
In order to map a many-to-many association, we use the @ManyToMany, @JoinTable and @JoinColumn annotations. Let's have a closer look at them. The @ManyToMany annotation is used in both classes to create the many-to-many relationship between the entities.
InverseJoinColumn is used to customize the column name in the table of the associated class reference variable name. that column act as a foreign key.
The way you have it mapped, the User
is the managing side of the relationship, therefore it will be responsible for updating the join table.
Change the JoinTable
mapping from User
to Group
, and make the groupList
property of User
so it has the mappedBy
attribute. That will change the group to the managing side of the relationship, and make persist/update calls to the group manage the join table.
But take note of that, you won't be able to simply add a group to a user, save the user, and continue, you'll instead have to add a user to the group and save the group to see the changes, but having the bi-directional many-to-many hopefully you'll be closely managing that relationship anyway.
As already indicated, make the group owner of the relation if you don't need to cascade from the user side.
Then, try to use cascade=CascadeType.MERGE
to not delete cascade the user when you delete the group.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With