Invalidating JPA EntityManager session

dasp picture dasp · Mar 8, 2010 · Viewed 19.1k times · Source

A project I am working on uses Spring 2.5 & JPA with Hibernate as a provider.

My DAO classes extend JpaDaoSupport, so I get my JpaTemplate using the getJpaTemplate() method.

The back-end database can get changed either by my application, or a third-party application.

When a third-party application changes the database (mostly configuration data changes), I need to provide the user of my application a way to invalidate all JPA sessions and reload the new data (i.e. invalidate all the hibernate sessions in the background). This needs to be "seen" by all concurrent users of my application.

How can I do this?

Answer

ewernli picture ewernli · Mar 8, 2010

There are two levels of caches:

  • 1st level is the EntityManager's own cache.

    You can either refresh on one entity and it will be reloaded form the database, or you can clear the entity manager itself, in which case all entities are removed from the cache. There is no way with JPA to evict only one specific entity from the cache. Depending on the implementation you use, you can do this, e.g. Hibernate's evict method.

  • 2nd level caching is the global cache.

    JPA 1.0 did not provide support for 2nd level cache. You need then to rely on the underlying specific implementation, or to disable it. JPA 2.0 will address this issue with @Cache annotation and the cache API. You can clear the 2nd level cache using Hibernate-specific API, e.g. SessionFactory.evict(...).

Advanced issues with caching are:

  • Query cache

    Result of certain queries can be cached. Again not support for it in JPA 1.0, but most implementation have ways to specify which query will be cached and how.

  • Clustering

    Then comes also the tedious problem of synchronizing caches between nodes in a cluster. In this case, this mostly depend on the caching technology used, e.g. JBoss cache.

Your question is still somehow generic and the answer will depend on what you are exactly doing.

I worked on a system were many updates would be done without going through hibernate, and we finally disabled the 2nd level cache.

But you could also keep track of all opened sessions, and when necessary evict all 1st level cache of all opened session, plus the 2nd level cache. You would still need to manage synchronization yourself, but I imagine it's possible.