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

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


@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()只是为了能够删除该组,这似乎很荒谬。


牧羊人nacy
浏览 1062回答 3
3回答

绝地无双

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

慕森卡

以下对我有用。将以下方法添加到不是关系(组)所有者的实体@PreRemoveprivate void removeGroupsFromUsers() {&nbsp; &nbsp; for (User u : users) {&nbsp; &nbsp; &nbsp; &nbsp; u.getGroups().remove(this);&nbsp; &nbsp; }}请记住,要使此功能起作用,组必须具有更新的用户列表(不会自动完成)。因此,每次将“网上论坛”添加到“用户”实体中的群组列表时,也应将“用户”添加到“群组”实体中的用户列表中。

收到一只叮咚

我找到了可能的解决方案,但是...我不知道这是否是一个好的解决方案。@Entitypublic class Role extends Identifiable {&nbsp; &nbsp; @ManyToMany(cascade ={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})&nbsp; &nbsp; @JoinTable(name="Role_Permission",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; joinColumns=@JoinColumn(name="Role_id"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inverseJoinColumns=@JoinColumn(name="Permission_id")&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; public List<Permission> getPermissions() {&nbsp; &nbsp; &nbsp; &nbsp; return permissions;&nbsp; &nbsp; }&nbsp; &nbsp; public void setPermissions(List<Permission> permissions) {&nbsp; &nbsp; &nbsp; &nbsp; this.permissions = permissions;&nbsp; &nbsp; }}@Entitypublic class Permission extends Identifiable {&nbsp; &nbsp; @ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})&nbsp; &nbsp; @JoinTable(name="Role_Permission",&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; joinColumns=@JoinColumn(name="Permission_id"),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; inverseJoinColumns=@JoinColumn(name="Role_id")&nbsp; &nbsp; &nbsp; &nbsp; )&nbsp; &nbsp; public List<Role> getRoles() {&nbsp; &nbsp; &nbsp; &nbsp; return roles;&nbsp; &nbsp; }&nbsp; &nbsp; public void setRoles(List<Role> roles) {&nbsp; &nbsp; &nbsp; &nbsp; this.roles = roles;&nbsp; &nbsp; }我已经尝试过了,并且有效。删除角色时,关系也将被删除(但不删除Permission实体);删除权限时,与角色的关系也将被删除(但不删除Role实例)。但是我们两次映射单向关系,并且两个实体都是该关系的所有者。这会导致一些问题休眠吗?哪种类型的问题?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java