Hello all!
We have found the following issue.
We are developing a console app using Hibernate 3.6.7 + ehcache 2.4.4 + Spring 3.0.5 + postgress sql.
the app just read data from the database, so we have configured a L2 cache as read-only.
Sometimes the data in the database changes, so we need to refresh the cache.
In the past we used to use the methods
of sessionFactory for refreshing the cache, but we found that they are deprecated, so we have change our implementation to use (as say in hibernateĀ“s documentation) the methods
of Cache ([sessionFactory.getCache())
we made the refactor to use the indicated methods and the cache was not evicted. we found that the queries cache was not being evicted.
we think that the method Cache.evictQueryRegions() is not working properly so we have debuged hibernateĀ“s code to see what is happening...
we found the following in SessionFactoryImpl (line 1108)
Code:
public void evictQueryRegions() {
for ( QueryCache queryCache : queryCaches.values() ) {
queryCache.clear();
// TODO : cleanup entries in queryCaches + allCacheRegions ?
}
}
The question is if that "TODO" is responsible of hibernate bad cache evicting
there are 3 "TODO"s more in that class, in lines 1102 (method evictQueryRegion(String regionName)), 548 and 568 (method checkNamedQueries()), all of them "suspiciously" in methods that manages the queries caches.
To solve this problem we have called the following method assuming that we will have always the same SessionFactory implementation
Code:
((SessionFactoryImpl) this.sessionFactory).getQueryCache().clear();
then calling
Code:
LOG.debug("Evict all entries from the second-level cache.");
for (String entityName : this.sessionFactory.getStatistics().getEntityNames()) {
this.sessionFactory.getCache().evictEntityRegion(entityName);
}
LOG.debug("Evict all entries from the second-level cache.");
for (String roleName : this.sessionFactory.getStatistics().getCollectionRoleNames()) {
this.sessionFactory.getCache().evictCollectionRegion(roleName);
}
LOG.debug("Evict any query result sets cached in the named query cache region.");
for (String regionName : this.sessionFactory.getStatistics().getSecondLevelCacheRegionNames()) {
this.sessionFactory.getCache().evictQueryRegion(regionName);
}
Cheers Julio