我现在尝试深入研究一些Hibernate机制,我真的很难与级联机制斗争。
我找到了this really excellent answer(当然还有更多的网站,但这是一个很好的总结)关于Cascade.REMOVE和孤儿删除,我觉得这完全解释了我的机制。
然而,在测试我的数据模型时,我偶然发现了一个让我再次怀疑自己知识的问题。
我有两个实体定义如下:
@Entity
public class Parent {
....
@OneToMany(mappedBy="parent", fetch=FetchType.EAGER, cascade={ CascadeType.REMOVE })
@Fetch(FetchMode.SUBSELECT)
private List<Child> children;
...
}
----
@Entity
public class Child {
...
@ManyToOne
private Parent parent;
....
}
但是,在我的测试用例中,我使用一个子节点创建并保留父实例。
当我致电em.remove(myChildEntity)
时,一切都按预期工作。
但是当我调用em.remove(myParentEntity)
时,我遇到以下错误:
Referential integrity constraint violation: "FK_TA9YL3WAEU74UG94QYYBU4SWY: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement:
delete from Parent where id=?
所以对我来说,当我认为Hibernate实际上会先级联并删除Parent
实体时,它似乎只是试图删除Child
实体。观察到的行为似乎得到了我在Stackoverflow上找到的以下答案的支持:https://stackoverflow.com/a/20287817/2426346
我知道我的问题的解决方案是首先手动删除相关的Child
实体,但是如果有可能增长的数据模型,我显然更喜欢自动解决方案。
所以我的问题是:在我的案例中哪个答案是正确的,为什么? Hibernate显然不会在我的情况下级联删除,但这是因为我的配置错误还是设计错误?