I'm using a local ehcache as 2nd level cache for hibernate, got the following problem:
Since collections are cached separately from their owner entities, whenever an element of such cached collection is deleted etc.,
I gotta evict the collection manually. Now since transactions in this project are not instantaneous, I just keep track of inserted/deleted/updated
collection elements in hibernate postXXXEventListeners and postpone eviction until the transaction actually completes (using Spring's TransactionSynchronization
for that purpose). However, concurrent threads sometimes manage to read collections which are about to be evicted, producing EntityNotFoundExceptions:
Code:
javax.persistence.EntityNotFoundException: Unable to find com.acme.alarms.dto.DevAmplifierActiveAlarm with id 22630
at org.hibernate.ejb.Ejb3Configuration$Ejb3EntityNotFoundDelegate.handleEntityNotFound(Ejb3Configuration.java:113)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:171)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.ManyToOneType.assemble(ManyToOneType.java:219)
at org.hibernate.collection.PersistentSet.initializeFromCache(PersistentSet.java:147)
at org.hibernate.cache.entry.CollectionCacheEntry.assemble(CollectionCacheEntry.java:58)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.initializeCollectionFromCache(DefaultInitializeCollectionEventListener.java:159)
at org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:71)
at org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1743)
...
Apparently, I gotta invalidate these entries until they're evicted so that concurrent reads are deflected to DB, but I have no idea how.
Is there a way to do this in Ehcache?