JPA Hibernate多对多级联

时间:2011-02-08 15:42:21

标签: hibernate jpa many-to-many jpa-2.0 cascade

我正在使用JPA 2.0和hibernate。我有一个User类和一个Group类,如下所示:

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
}

然后,我创建一个用户和组,然后将用户分配给该组。

我想要的是当我删除该组时,该组将被删除(当然),该组所拥有的所有用户组关系将自动从USER_GROUP连接表中删除,但用户本身不是从USER表中删除。

使用上面的代码,删除组时,只删除GROUP表中的行,用户仍然会在USER_GROUP连接表中有一个已删除组的条目。

如果我将Cascade放在User类中,如下所示:

@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "USER_GROUP",
joinColumns =
{
    @JoinColumn(name = "GROUP_ID")
},
inverseJoinColumns =
{
    @JoinColumn(name = "USER_ID")
})
private Set<Group> groupList;

当我删除该组时,该用户也将被删除!

有没有办法达到我想要的目的?

4 个答案:

答案 0 :(得分:37)

映射的方式,User是关系的管理方,因此它将负责更新连接表。

JoinTable映射从User更改为Group,并将groupList属性设为User,使其具有mappedBy属性。这会将组更改为关系的管理方,并使对组的持久/更新调用管理连接表。

但请注意,您将无法简单地向用户添加组,保存用户,并继续,您将不得不将用户添加到组并保存组以查看变化,但有双向多对多,希望你会密切管理这种关系。

答案 1 :(得分:5)

从另一个角度看问题:

您可以向多对多映射表添加FK约束。实际上,出于数据完整性原因,您应始终在DB中使用FK。例如,在这种情况下,至少在映射表中静默留下孤立行时无法删除用户。

如果你有FK,你可以在约束上指定on delete cascade referential action,数据库将管理自动删除映射表,但不会像你要求的那样管理实体。

答案 2 :(得分:4)

如前所述,如果您不需要从用户端进行级联,请创建关系的组所有者。

然后,尝试使用cascade=CascadeType.MERGE在删除组时不删除级联用户。

答案 3 :(得分:0)

您可以这样做

@PreRemove
private void removeMembers() {
    this.memberList.clear();
}