14 sept. 2010

Howto: Hibernate second-level cache with Ehcache Part 2

In Part 1, we explained briefly what is Hibernate's second level cache and how it works.

Let's see how to configure our project. We'll asume a working Hibernate project using JPA annotations. The project will be built with Maven, using the standard folder layout for webapps (src, resources, webapp, etc).
  1. First, we must add Ehcache dependency to pom.xml:
    <dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.0.1</version>
    <type>pom</type>
    </dependency>
  2. We have to configure Hibernate to use a second-level cache with Ehcache. We're using hibernate.properties file in this example:
    hibernate.cache.use_second_level_cache=true
    hibernate.cache.use_query_cache=true
    hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory
  3. For setup and development purposes, it's always a good idea to enable Hibernate cache specific logging. The logger is org.hibernate.cache
  4. Now, let's annotate our domain entity to be cacheable:
    @Entity
    @Table(name = "FooEntity")
    @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public class FooEntity {
    ...
    // implementation for FooEntity
    ...
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    public Set getBars() { ... }
    }
    We use the Hibernate specific @Cache annotation to define a cacheable entity or collection. The usage attribute defines cache concurrency strategies that implies different isolation levels for cache read-write.
  5. Next, we have to configure Ehcache. This is done with a ehcache.xml file that must exist at the root of the classpath for our project (WEB-INF/classes probably). The location of this file can be cofigured with a Hibernate configuration property net.sf.ehcache.configurationResourceName = org/mycompany/ehcache.xml (this is a relative path to the project's classpath root). Take a look at Ehcache's web site for a full explanation of this configuration file:
    <?xml version="1.0" encoding="UTF-8" ?>
    <ehcache>
    <diskStore path="java.io.tmp" />

    <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="true" />

    <cache name="org.myconpany.model.FooEntity"
    maxElementsInMemory="50"
    eternal="false"
    timeToIdleSeconds="600"
    timeToLiveSeconds="600"
    overflowToDisk="false" />
    </ehcache>

    <cache name="org.myconpany.model.BarEntity"
    maxElementsInMemory="500"
    eternal="false"
    timeToIdleSeconds="600"
    timeToLiveSeconds="600"
    overflowToDisk="false" />
    </ehcache>
  6. We're done! With that, FooEntity instances loaded via Session's get() and load() methods will be stored in the second-level Ehcache.
References:

No hay comentarios: