【问题标题】:Order of Hibernate delete queriesHibernate 删除查询的顺序
【发布时间】:2009-06-04 14:49:28
【问题描述】:

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

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先删除人,然后删除组?我的模型有缺陷吗?

【问题讨论】:

    标签: java hibernate


    【解决方案1】:

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

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

    更新: 再次阅读您的数据模型,这里的人可能缺少可以解释行为的注释。您是否在与 people->group 的链接上设置了级联?这可以解释为什么第一个语句首先会尝试删除组。大概您会想要为不层叠的人的组添加注释?

    【讨论】:

      【解决方案2】:

      有两种选择

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

      2) 为您的映射添加一个“级联”:即 cascade="delete"。删除群组会同时删除群组成员。

      【讨论】:

      • 如何在 Group 和 People 之间添加级联删除?
      【解决方案3】:

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

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

      如果子对象(在本例中为 Person)可以有多个父对象,那么第二部分就很重要了,因此除非删除每个父关系,否则不应删除子对象。

      【讨论】:

        猜你喜欢
        • 2021-07-29
        • 2020-04-15
        • 2020-04-21
        • 2022-08-03
        • 1970-01-01
        • 1970-01-01
        • 2014-07-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多