We have an application that uses Hibernate\'s 2nd level caching to avoid database hits.
I was wondering if there is some easy way to invalidate the Java application
Both hibernate and JPA now provide direct access to the underlying 2nd level cache:
sessionFactory.getCache().evict(..);
entityManager.getCache().evict(..)
I was searching how to invalidate all Hibernate caches and I found this useful snippet:
sessionFactory.getCache().evictQueryRegions();
sessionFactory.getCache().evictDefaultQueryRegion();
sessionFactory.getCache().evictCollectionRegions();
sessionFactory.getCache().evictEntityRegions();
Hope it helps to someone else.
You may try doing this:
private EntityManager em;
public void clear2ndLevelHibernateCache() {
Session s = (Session) em.getDelegate();
SessionFactory sf = s.getSessionFactory();
sf.getCache().evictQueryRegions();
sf.getCache().evictDefaultQueryRegion();
sf.getCache().evictCollectionRegions();
sf.getCache().evictEntityRegions();
return;
}
I hope It helps.
SessionFactory has plenty of evict()
methods precisely for that purpose:
sessionFactory.evict(MyEntity.class); // remove all MyEntity instances
sessionFactory.evict(MyEntity.class, new Long(1)); // remove a particular MyEntity instances
One thing to take into account when using distributed cache is that QueryCache is local, and evicting it on one node, does not evicts it from other. Another issue is - evicting Entity region without evicting Query region will cause N+1 selects,when trying to retrieve date from Query cache. Good readings on this topic here.
Based on ChssPly76's comments here's a method that evicts all entities from 2nd level cache (we can expose this method to admins through JMX or other admin tools):
/**
* Evicts all second level cache hibernate entites. This is generally only
* needed when an external application modifies the game databaase.
*/
public void evict2ndLevelCache() {
try {
Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata();
for (String entityName : classesMetadata.keySet()) {
logger.info("Evicting Entity from 2nd level cache: " + entityName);
sessionFactory.evictEntity(entityName);
}
} catch (Exception e) {
logger.logp(Level.SEVERE, "SessionController", "evict2ndLevelCache", "Error evicting 2nd level hibernate cache entities: ", e);
}
}