Hibernate删除查询的顺序

时间:2009-06-04 14:49:29

标签: java hibernate

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

public class AddressBook {
    private List<Group> groups = new ArrayList<Group>();
    private List<People> peoples = new ArrayList<People>();

    @OneToMany(mappedBy = "addressbook", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    public List<Group> 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<People> 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首先删除人员,然后是群组?我的模型中有缺陷吗?

3 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

有两个选项

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

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

答案 2 :(得分:0)

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

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

如果子对象(本例中为Person)可以有多个父对象,那么第二部分是一个大问题,因此除非删除每个父关系,否则不应删除子对象。