Hibernate删除查询的顺序

这是我的数据模型(简化),

public class AddressBook { private List groups = new ArrayList(); private List peoples = new ArrayList(); @OneToMany(mappedBy = "addressbook", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) public List getGroups() { return groups; } @OneToMany(mappedBy = "addressbook", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN) public List getPeoples() { return peoples; } } public class Group { private AddressBook addressBook; @ManyToOne(fetch = FetchType.LAZY, optional = false) public void setAddressBook(AddressBook addressBook) { this.addressBook = addressBook; } } public class People { private AddressBook addressBook; private Group group; @ManyToOne(fetch = FetchType.LAZY, optional = false) public AddressBook getAddressBook() { return addressBook; } public Group getGroup() { return group; } } 

我想从我的地址簿中删除一个完整的组,以及属于该组的所有人。 所以我做了类似的事情:

 adressBook.getPeople().removeAll(peopleBelongingToGroupA); adressBook.getGroups().remove(groupA); 

但是当我的事务被提交时,Hibernate会先做:

 delete from groups where groupName='groupA'; 

而不是先删除人。 这会导致违反人和组之间的FOREIGN_KEY约束。

有没有办法告诉hibernate首先删除人,然后是群组? 我的模特有缺陷吗?

您是否尝试过在每个@ManyToOne上设置级联。 您只在许多方面指定了AddressBook上的级联删除。 这个属性适用于我认为的每个协会。

编写这些bean时,EJB3.0规范非常值得一试。 见http://jcp.org/en/jsr/detail?id=220

更新:再次读取您的数据模型,这里的人可能会缺少注释来解释行为。 您是否在人员 – >组的链接上设置了级联? 这可以解释为什么第一个语句首先会尝试删除该组。 大概你会想要一个没有级联的人群的注释吗?

有2个选项

1)在第二次删除之前调用flush

2)在映射中添加“级联”:即cascade =“delete”。 删除该组将删除也删除该组的成员。

您可以将其作为两个事务执行,也可以像有人提到的那样使用cascade = delete。 实际上,您可能希望删除孤立,它会进行级联删除,但只有在完全孤立时才删除Person。 这有两件好事:

1)您所做的只是删除组,它会自动删除子项(假设您的映射设置正确)。 2)如果一个Person可以属于多个组,它只会删除那个子Person对象,如果它是孤立的,这意味着没有组引用它。

如果子对象(在这种情况下是人)可以有多个父对象,那么第二部分是一个大问题,因此除非删除每个父关系,否则不应删除子对象。