JPA 2.0 standardized the Hibernate second level cache and introduced a new cache API.
There are 3 built-in cache implementation shipped with Hibernate 4, HashTable, Ehcache, Infinispan. HashTable is a in-memory solution, it is useful to test purpose. Ehcache is one of the most popular cache solutions,
Hibernate provides integration with Ehcache. Infinispan is also from JBoss.org community, it is the base of JBoss's next-generation cache and datagrid solution, infinispan is the recommended cache solution if you are using Hibernate/JPA in JBoss application servers.
By default, JPA 2nd level cache is disabled.
You must specify the value of javax.persistence.sharedCache.mode property or shared-cache-mode element in persistence.xml file.
javax.persistence.sharedCache.mode=ENABLE_SELECTIVE
or
ENABLE_SELECTIVE
There are four optional values, ALL, ENABLE_SELECTIVE, DISABLE_SELECTIVE, NONE.
ALL will enable cache for all entities, ENABLE_SELECTIVE and DISABLE_SELECTIVE should be used with the JPA specific @Cacheable
annotation. The former will enable cache for the entities annotated with @Cacheable
or @Cacheable(true)
. The later will DISABLE cache for the entities annotated with @Cacheable(false)
and enable cache for other entities. NONE will disable cache for all entities.
Now you need configure some properties for Hibernate specific cache provider.
An example of using Ehcache as backend cache provider.
hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=true hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory
hibernate.cache.use_query_cache
is use for enable cache for JPA query result.
It also require you add extra dependency in your pom.xml file.
org.hibernate hibernate-ehcache
Add @Cacheable(true)
to the entity class, we are using the ENABLE_SELECTIVE cache strategy and must apply this annotation to enable cache.
@Entity @Cacheable(true) //@Cache(usage=CacheConcurrencyStrategy.READ_ONLY, region="conf_region") public class Conference { }
Hibernate also provides specific @Cache
annotation to tune the cache settings. Please read the official Hibernate Document for more detailed info.
Write some codes for test purpose and enable the logging info.
@Test @Transactional public void retrieveConference() { log.debug("============beginning of calling retrieveConference==========="); final Long id = 1L; Conference conference = conferenceDao.findById(id); assertTrue(conference != null); assertTrue("JUD2013".equals(conference.getName())); Conference conference2 = conferenceDao.findById(id); assertTrue(conference == conference2); log.debug("============end of calling retrieveConference==========="); }
You will find the entity object is cached after it is persisted, and the later queries will not hint database at all.
The codes are hosted on my Github account.
https://github.com/hantsy/spring-sandbox
I also tried to add sample settings and codes for Infinispan, but failed to make it worked in the standalone test.