一尘不染

如何在JPA中删除具有ManyToMany关系的实体(以及相应的联接表行)?

hibernate

假设我有两个实体:“组”和“用户”。每个用户可以是多个组的成员,每个组可以有多个用户。

@Entity
public class User {
    @ManyToMany
    Set<Group> groups;
    //...
}

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

现在,我要删除一个组(假设它有很多成员)。

问题是,当我在某个组上调用EntityManager.remove()时,JPA提供程序(在我的情况下为Hibernate) 不会从联接表中删除行,
并且由于外键约束,删除操作也会失败。在User上调用remove()可以正常工作(我想这与拥有关系的一方有关)。

那么在这种情况下如何删除组?

我想出的唯一方法是加载组中的所有用户,然后为每个用户从其组中删除当前组并更新用户。但是,对于该组中的每个用户调用update()只是为了能够删除该组,这似乎很荒谬。


阅读 376

收藏
2020-06-20

共1个答案

一尘不染

  • 关系的所有权取决于将“ mappedBy”属性放置在注释中的位置。您放置“ mappedBy”的实体不是所有者。双方都没有机会成为所有者。如果您没有“删除用户”用例,则可以简单地将所有权移至Group实体,因为当前User是所有者。
  • 另一方面,您没有问过这个问题,但是有一件事值得知道。的groupsusers不与彼此组合。我的意思是,从Group1.users中删除User1实例后,User1.groups集合不会自动更改(这对我来说很令人惊讶),
  • 总而言之,我建议您确定谁是所有者。假设User是所有者。然后,在删除用户时,关系用户组将自动更新。但是,在删除组时,您必须像这样删除自己的关系:

entityManager.remove(group)
for (User user : group.users) {
     user.groups.remove(group);
}
...
// then merge() and flush()
2020-06-20