CascadeType.REMOVE
The CascadeType.REMOVE strategy, which you can configure explicitly:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.REMOVE
)
private List<PostComment> comments = new ArrayList<>();
or inherit it implicitly from the CascadeType.ALL strategy:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL
)
private List<PostComment> comments = new ArrayList<>();
allows you to propagate the remove operation from the parent entity to its child entities.
So, if we fetch the parent Post entity along with its comments collection, and remove the post entity:
Post post = entityManager.createQuery("""
select p
from Post p
join fetch p.comments
where p.id = :id
""", Post.class)
.setParameter("id", postId)
.getSingleResult();
entityManager.remove(post);
Hibernate is going to execute three delete statements:
DELETE FROM post_comment
WHERE id = 2
DELETE FROM post_comment
WHERE id = 3
DELETE FROM post
WHERE id = 1
The PostComment child entities were deleted because of the CascadeType.REMOVE strategy, which acted as if we removed the child entities as well.
The orphan-removal strategy
The orphan-removal strategy, which needs to be set via the orphanRemoval attribute:
@OneToMany(
mappedBy = "post",
cascade = CascadeType.ALL,
orphanRemoval = true
)
private List<PostComment> comments = new ArrayList<>();
allows you to remove the child table row upon removing the child entity from the collection.
So, if we load the Post entity along with its comments collection and remove the first PostComment from the comments collection:
Post post = entityManager.createQuery("""
select p
from Post p
join fetch p.comments c
where p.id = :id
order by p.id, c.id
""", Post.class)
.setParameter("id", postId)
.getSingleResult();
post.remove(post.getComments().get(0));
Hibernate is going to execute a DELETE statement for the associated post_comment table row:
DELETE FROM post_comment
WHERE id = 2