Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?

Let's say I have two entities: Group and User. Every user can be member of many groups and every group can have many users.

@Entity public class User {     @ManyToMany     Set<Group> groups;     //... }  @Entity public class Group {     @ManyToMany(mappedBy="groups")     Set<User> users;     //... } 

Now I want to remove a group (let's say it has many members).

Problem is that when I call EntityManager.remove() on some Group, JPA provider (in my case Hibernate) does not remove rows from join table and delete operation fails due to foreign key constrains. Calling remove() on User works fine (I guess this has something to do with owning side of relationship).

So how can I remove a group in this case?

Only way I could come up with is to load all users in the group, then for every user remove current group from his groups and update user. But it seems ridiculous to me to call update() on every user from the group just to be able to delete this group.

like image 281
rdk Avatar asked Jul 04 '09 12:07

rdk


People also ask

How do I delete a many-to-many relationship in JPA?

If you are using Spring Data Jpa, then simply create a repository interface for the owner class Group. class , then use their deleteById(Long id) method extended from JpaRepository. class .


1 Answers

  • The ownership of the relation is determined by where you place the 'mappedBy' attribute to the annotation. The entity you put 'mappedBy' is the one which is NOT the owner. There's no chance for both sides to be owners. If you don't have a 'delete user' use-case you could simply move the ownership to the Group entity, as currently the User is the owner.
  • On the other hand, you haven't been asking about it, but one thing worth to know. The groups and users are not combined with each other. I mean, after deleting User1 instance from Group1.users, the User1.groups collections is not changed automatically (which is quite surprising for me),
  • All in all, I would suggest you decide who is the owner. Let say the User is the owner. Then when deleting a user the relation user-group will be updated automatically. But when deleting a group you have to take care of deleting the relation yourself like this:

entityManager.remove(group) for (User user : group.users) {      user.groups.remove(group); } ... // then merge() and flush() 
like image 173
Grzegorz Oledzki Avatar answered Sep 27 '22 16:09

Grzegorz Oledzki