Question

I've got this spring/hibernate project which I'm trying to add 2nd level cache to hibernate via ehcache and terracotta. Everything seems to plug fine, I can even see in the terracota console the entries for the entities I'm trying to cache. But based on the statistics and log from the DB there's nothing cached at all!

The load hit ratio is 0%, the load statistics is 0 as well. What is that that I'm doing wrong?

Here is what I did, I added the required jars via maven.

        <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache-core</artifactId>
                <version>2.5.2</version>
        </dependency>
        <dependency>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache-terracotta</artifactId>
                <version>2.5.2</version>
        </dependency>
        <dependency>
                <groupId>org.terracotta</groupId>
                <artifactId>terracotta-toolkit-1.5-runtime</artifactId>
                <version>4.2.0</version>
        </dependency>

Changed my hibernate properties to enable 2nd level cache

<property name="hibernateProperties">
            <props>
                ...
                <prop key="hibernate.cache.use_second_level_cache">true</prop>
                <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>
                <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
                <prop key="hibernate.cache.use_query_cache">true</prop>
                <prop key="hibernate.cache.use_structured_entries">true</prop>
                <prop key="hibernate.cache.generate_statistics">true</prop>
            </props>
        </property>

Added the @Cache annotation to my test entity

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class User implements java.io.Serializable
 {
...
}

Here is my extremely simple ehcache.xml (I also tried setting a cache entry for my entity with the same result)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache >    
    <defaultCache  
        maxElementsInMemory="10000"   
        eternal="false" 
        maxEntriesLocalHeap="10"         
        timeToIdleSeconds="120"         
        timeToLiveSeconds="120">        
        <terracotta/>    
    </defaultCache>        
    <terracottaConfig         
        url="localhost:9510"/>
</ehcache>

And after I start my terracotta server and run my test code

@Test
    @Transactional
    @Rollback(false)
    public void testCache() {
        long start = System.currentTimeMillis();
        List<User> list = userRepository.listAll(0, 100);
        long end = System.currentTimeMillis();
        log.info("Total time "+(end-start));
        assertNotNull(list);
        assertThat(list.size(), is(100));

        for (int i=0; i<100; i++) {
            long start2 = System.currentTimeMillis();
            list = userRepository.listAll(0, 100);
            long end2 = System.currentTimeMillis();
            log.info("Total time 2 "+(end2-start2));
        }
        assertNotNull(list);
        assertThat(list.size(), is(100));
    }

My log shows 100 SQL which shouldn't occurred. It also shows hit ratio as 0%.

Here are some screen shots from the terracotta console while my test is running.

What is that last piece that I need in order to have this working?

2nd level cache statistics ehcache overview Entity statistics

Was it helpful?

Solution

Found the solution to the problems I was experimenting, here are the details:

  • The statistics weren't getting set due to a wrong key in the hibernate properties

Use this (note no .cache. )

<prop key="hibernate.generate_statistics">true</prop>

instead of

<prop key="hibernate.cache.generate_statistics">true</prop>
  • The queries wasn't getting cached since I was not using ".setCachable(true)" for the method that was in charge of listing/loading the entities.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top