How to remove entity with ManyToMany relationship in JPA (and corresponding join table rows)?
hibernate, java, jpa, orm
Solution
- 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()
Problem
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.