0% found this document useful (0 votes)
18 views4 pages

Avoiding CascadeType.REMOVE Issues

CascadeType.REMOVE should be avoided for to-many associations as it can lead to unintended deletion of entities and poor performance. When removing entities with to-many relationships, it is better to manually delete each association rather than letting Hibernate cascade deletes, or to use bulk delete queries to remove multiple associations at once.

Uploaded by

Adolf
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views4 pages

Avoiding CascadeType.REMOVE Issues

CascadeType.REMOVE should be avoided for to-many associations as it can lead to unintended deletion of entities and poor performance. When removing entities with to-many relationships, it is better to manually delete each association rather than letting Hibernate cascade deletes, or to use bulk delete queries to remove multiple associations at once.

Uploaded by

Adolf
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Why you should avoid CascadeType.

REMOVE
The CascadeTypes REMOVE and ALL, which includes REMOVE,
provide a comfortable option to remove an entity together with all its
child entities.

But it creates several issues for to-many associations, and you should
only use it for to-one relationships.

Problems for To-Many Associations


Too Many Queries
When you use [Link], Hibernate loads all associated
entities and deletes them one by one. Depending on the size of the
relationship, this might require a lot of queries and slow down your
application.

Remove More Than You Expected


When you use [Link] on a many-to-many
association, Hibernate removes all child entities. That includes the
entities that are still associated to other parent entities.
So, in the following example Hibernate removes Book 1 and Book 2,
even so Book 2 was still associated to Author 2.

[Link]
Why you should avoid [Link]
And it gets even worse when you specify the [Link]
on both ends of the association. Hibernate then keeps cascading the
remove operation until there are no associated entities left.

Solution
First of all, you shouldn't use the [Link] for to-many
associations. And that's also the case for [Link] which
includes the [Link].
When you don't use cascading, you need to delete the associated
entities yourself. You can either do that by calling the remove
method of the EntityManager for each entity or with a bulk
operation.

Remove One By One


That is the easiest but not the most efficient approach. But you can,
at least, be sure that you don't delete any records by accident.

[Link]
Why you should avoid [Link]
You need to iterate through the list of associated Books and check if
it's associated with any other Author. If it's not, you call the remove
method for it. Otherwise, you just delete the association to the
Author entity.

Author a = [Link]([Link], 1);


for (Book b : [Link]()) {
if ([Link]().size() == 1) {
[Link](b);
} else {
[Link]().remove(a);
}
}
[Link](a);
As I said, this is not a very efficient approach. Hibernate has to
perform 2 SQL DELETE operations for each Book entity you want to
remove. One to remove the Book entity and another one to remove
the records from the association table. And if you just want to
remove the association to the Author entity, Hibernate has to delete
the record from the association table.

Bulk Remove
When your association contains a lot of entities, it's better to remove
them with a few queries.
This approach is much more complicated than the one I showed you
before. But it needs a fixed number of queries and performs much
better for huge associations.
You first get the ids of all Books that Author 1 wrote alone and store
them in a List. These are the ones you need to delete in a later step.

[Link]
Why you should avoid [Link]
Then you remove all records from the association table that are
linked to Author 1. That allows you to remove Book 1 without violating
a foreign key constraint.
Now you use the List you got in step 1 and remove all Books that
Author 1 wrote alone.
And in the final step, you remove the Author entity.

Author a = [Link]([Link], 1);

// get all books that this author wrote alone


Query q = [Link]("SELECT [Link] FROM
BookAuthor ba JOIN Book b ON [Link] = [Link] JOIN
BookAuthor ba2 ON [Link] = [Link] WHERE [Link]
= ? GROUP BY [Link] HAVING count([Link]) = 1");
[Link](1, [Link]());
List<Integer> bookIds = (List<Integer>)[Link]();

// remove all associations for this author


q = [Link]("DELETE FROM BookAuthor ba
WHERE [Link] = ?");
[Link](1, [Link]());
[Link]();

// remove all books that this author wrote alone


q = [Link]("DELETE FROM Book b WHERE
[Link] IN (:ids)");
[Link]("ids", bookIds);
[Link]();

// remove author
[Link](a);

[Link]

You might also like