I try to dive into some Hibernate mechanics at the moment and I really struggle with the cascade mechanisms.
I found this really excellent answer (and many more sites of course, but thats a nice summary) about Cascade.REMOVE and orphan removal which I felt fully explained the mechanics to me.
Yet, during testing my data model, I stumbled upon a problem that made me doubt my knowledge again.
I have two entities defined as follows:
@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;
....
}
However, in my testcase I create and persist a parent instance with one child.
When I call em.remove(myChildEntity)
, everything works as expected.
But when I call em.remove(myParentEntity)
, I run into the following error:
Referential integrity constraint violation: "FK_TA9YL3WAEU74UG94QYYBU4SWY: PUBLIC.CHILD FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.PARENT(ID) (1)"; SQL statement:
delete from Parent where id=?
So to me it seems that Hibernate simply tries to delete the Parent
entity when I thought that it would actually cascade and delete the Child
entity first. The observed behaviour seems to be backed by the following answer I found on Stackoverflow: https://stackoverflow.com/a/20287817/2426346
I know that a solution for my problem would be to manually delete the relevant Child
entities first, but with a potentially growing datamodel I would obviously prefer an automatic solution.
So my question is: Which answer is the correct one in my case and why? Hibernate obviously does not cascade the remove in my case, but is this because of a configuration error on my side or is it by design?