Dude, Where’s My Hibernate Second-Level Ehcache Hit?

This post, in which we assume you use Spring, shows how to confirm that your hibernate second-level cache is working, which is one of the first things you would want to do after you have completed the necessary configuration.

Trying to use ehcache DEBUG log output to confirm your cache is working may end up wasting your time, rather use the approach documented here.

Step 1: Tell Hibernate to collect statistics in your test spring context

The new line you will include is hibernate.generate_statistics line shown below.

<prop key="hibernate.query.startup_check">false</prop>
<prop key="hibernate.hbm2ddl.auto">create-drop</prop>
<!-- Enable the second-level cache  -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<prop key="hibernate.generate_statistics">true</prop>

Step 2: Create a JUnit test case where you expect a cache hit and check for the hit

You would have, in your ehcache.xml config file, created a cache for each DBO (i.e. JPA @Entity) that you want to have cached. So, now simply create a unit test where you create a set of objects that should be cached, then fetch them, from the cache (hopefully).

Include the following in your Test class, if its not there already:

@Autowired
private ApplicationContext applicationContext;

Now write a test case such as the following:

@Test
public void testGenerateStuff() {
   int stuffNumber = databaseHelper.generateStuff();
   Stuff stuff = databaseHelper.getStuff(stuffNumber);
   // Pertinent lines ...
   EntityManagerFactoryInfo entityManagerFactoryInfo = (EntityManagerFactoryInfo) applicationContext.getBean("entityManagerFactory");
   EntityManagerFactory emf = entityManagerFactoryInfo.getNativeEntityManagerFactory();
   EntityManagerFactoryImpl emfImp = (EntityManagerFactoryImpl)emf;
   Statistics stats = emfImp.getSessionFactory().getStatistics();
   printStats(stats);
   assertTrue(stats.getSecondLevelCacheHitCount() > 0);
}

public static void printStats(Statistics stats) {
   System.out.println(stats.toString());
   System.out.println("Second Level Cache Put Count ==> " + stats.getSecondLevelCachePutCount());
   System.out.println("Second Level Cache Hit Count ==> " + stats.getSecondLevelCacheHitCount());
   System.out.println("Second Level Cache Miss Count ==> " + stats.getSecondLevelCacheMissCount());
}
Advertisements