TL;DR: Is it possible to configure Hibernate to delete all child objects using a single delete query?
Full Question: I have the following parent/child association defined in Hibernate 5.1:
public class Parent {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "parent", cascade = CascadeType.REMOVE)
private List<Child> children;
}
public class Child {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "parent_id", nullable = false)
private Parent parent;
}
When I delete the parent object, all of the child objects are deleted, as expected, but each one is deleted individually. In my application a parent could have many thousands of children, so for performance reasons I need to use a single query to delete them all at once.
Possible Workarounds
- Manually execute my own HQL query,
DELETE FROM child WHERE parent_id = ?
, prior to deleting the parent. The downside here is that I (and any other developers) have to remember to call the method. Plus, it essentially circumvents the cascade delete. - Allow the cascade delete to happen at the database level. Since data is changing behind the scenes, I assume I would need to remember to manually
.clear()
the child collection to prevent disparity between Hibernate and the database.
Edit: I see older versions of Hibernate used to have the concept of a one-shot delete but I cannot find anything similar in the documentation for the latest version. Has that functionality been removed?
Best Answer
Either set the ON DELETE CASCADE in the data base explicitly, or mark the required Child entity with the annotation @org.hibernate.annotations.OnDelete, which automatically adds the "on delete" to schema during the schema generation. For your example it would be,