Hibernate: 在联接表上设置级联删除操作

5
我有两个实体之间的多对多关系,分别是“菜单组”和“页面”,具体如下:
    public class MenuGroup {
        @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
        @JoinTable(name = "menu_group_pages",schema="live",    
                  joinColumns=@JoinColumn(name="menu_groups_id"),
                  inverseJoinColumns=@JoinColumn(name="pages_id"))
        private Set<Page> pages = new HashSet<Page>();
    }

    public class Page {
       @ManyToMany(fetch = FetchType.EAGER, mappedBy="pages", 
                   cascade={CascadeType.MERGE})

       private Set<MenuGroup> menuGroups = new HashSet<MenuGroup>();
    }

正如您所看到的,这里有一个连接表,其中包含两个外键:menu_groups_id和pages_id。现在我想要为这个连接表中的“pages_id”外键添加“on delete cascade”操作。对于普通表格,语句类似于:

    @OnDelete(action=OnDeleteAction.CASCADE)

我该如何在联合表中实现这个?谢谢。
2个回答

2
您需要手动在数据库中设置级联选项,然后只需调用托管的Page对象上的remove方法,即可将其从链接表中删除。
OnDelete注释应该已经在数据库中生成了级联选项,但似乎对ManyToMany关系不起作用(HHH-4404)。
另一方面,如果您想避免进行任何模式更改,则只需删除MenuGroup和Page之间的关联。在您的PageDAO(或任何抽象层)中,您可以编写一个remove方法来删除这些关联。
public void remove(Page page) {
    for(MenuGroup menuGroup : page.getMenuGroups()){
        menuGroup.getPages().remove(page);
    }
    session.remove(page);
}

0
我认为你只需要在你的ManyToMany注释中设置CascadeType,包括CascadeType.Remove。如果符合你的数据模型,你也可以使用CascadeType.All。这两种方法都应该将删除级联到Page\ManuGroup表以及连接表。

2
你好,感谢您的回复。如果我在Page类中设置CascadeType.Remove,那么当我删除一个页面时,相应的菜单组也将被删除。当我删除一个页面时,我只想删除连接表中的关系,而不是MenuGroup实体。这就是为什么我没有使用CascadeType.REMOVE的原因。对此有什么建议吗? - Raistlin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接