I have an application using JPA, Hibernate and ehcache, as well as Spring's declarative transactions. The load on DB is rather high so everything is cached to speed things up, including collections. Now it is not a secret that collections are cached separately from the entities that own them so if I delete an entity that is an element of such cached collection, persist an entity that should be an element of one, or update an entity such that it travels from one collection to another, I gotta perform the eviction by hand.
So I use a hibernate event listener which keeps track of entities being inserted, deleted or updated and saves that info for a transaction synchronization registered with Spring's transaction manager to act upon. The synchronization then performs the eviction once the transaction is committed.
Now the problem is that quite often, some other concurrent transaction manages to find a collection in the cache that has just been evicted (these events are usually tenths of a second apart according to log) and, naturally, causes an EntityNotFoundException to occur.
How do I synchronize this stuff correctly?
I tried doing the eviction in each of the 4 methods of TransactionSynchronization (which are invoked at different points in time relative to transaction completion), it didn't help.