Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: Clean collection's 2nd level cache while cascade delete items

I have a problem Hibernate does not update 2nd level cache for a collection of items which are subject of cascade removal.

Details

Assume we have an object Parent which has Parent.myChildren collection of Child objects. Now we have also object Humans with Humans.myAllHumans collection and all Parent and Child objects are in that collection.
Now we session.delete(parent) and all the children are cascade removed from the database, but Humans.myAllHumans collection's cache is not updated! It still assumes that cascade deleted objects are in database and we hit following exception while trying to iterrate the collection later:
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [foo.Child#751]

Approaches tried

1) I've tried SessionFactory.evictCollection() approach, but as I understand it is not transaction safe and hard removes data from 2nd level cache, I do not want that.

2) I can also manually (programatically) remove each object from the myAllHumans collection. In this case hibernate does update 2nd level cache. This approach I'll like to avoid since it just makes cascade delete feature useless.

Expected

I'd like hibernate to be smart enough to update the collection's cache automatically. Is it possible?
I'm using EhCache now, do you think using another cache implementation or configuring EhCache may help?

like image 731
Yurii Soldak Avatar asked Sep 24 '09 08:09

Yurii Soldak


People also ask

Which 2nd level cache is better in Hibernate?

Hibernate second level cache uses a common cache for all the session object of a session factory. It is useful if you have multiple session objects from a session factory. SessionFactory holds the second level cache data. It is global for all the session objects and not enabled by default.

Which of the following is true about second level cache in Hibernate?

Q 16 - Whis of the following is true about second level cache in hibernate? A - The second-level cache is the SessionFactory based cache.

What are different ways to disable Hibernate second level cache?

To disable second-level caching (say for debugging purposes), we just set the hibernate. cache. use_second_level_cache property to false.

Is second level caching mandatory in Hibernate?

It is maintained at the Session level, and it's by default enabled. Now, let's come to the second-level cache. This is an optional Cache that Hibernate provides. Unlike the first-level cache which is accessible only to the session that maintains it, Second-level Cache is accessible to all Sessions.


2 Answers

The problem is that Hibernate doesn't actually do the delete. The database does that as part of a foreign key relationship, so Hibernate never sees all the objects that may get deleted and therefore, there is no way to update the cache that works in every case.

I think your best bet is to flush the cache (or part of it) when you delete.

like image 80
Aaron Digulla Avatar answered Sep 18 '22 15:09

Aaron Digulla


I've been struggling with other problem requiring remove collection from cache and I've worked out some solution. I don't know if it is possible to update the collection's cache automatically on cascade delete, but if you've tried SessionFactory.evictCollection() and it worked, I think that this solution can be transactional safe and it works also:

if (MYCOLLECTION instanceof AbstractPersistentCollection) ((AbstractPersistentCollection) MYCOLLECTION).dirty();

like image 45
Lukasz Frankowski Avatar answered Sep 19 '22 15:09

Lukasz Frankowski