Hibernate is able to cache entities or queries using two distinct query mechanism. The first level cache and the second level cache. In this tutorial we will shortly recap the two kind of caches and the configuration needed to get it running with JBoss 5-6-7 using either JPA 1 and JPA 2 annotations.
Hibernate first level cache
As we said the first level cache is associated with the current session and is used to reduce the number of SQL statements within the same transaction. It's on by default. Let's see an example :
Here, we are issuing two session.load to retrieve the User object using its primary key. Here only the first query hits the database. his can be verified by adding the following property to your persistence.xml, which displays the sql which is sent to the DB:
Note: The System.out.println calls by the way are required to force Hibernate to load data at all. If we would not put them in, nothing would get loaded. This is because data is always by default loaded lazyly in Hibernate.
Hibernate second level cache
The second level cache is used across sessions, which also differentiates it from the session cache, which only – as the name says – has session scope. Hibernate provides a flexible concept to exchange cache providers for the second-level cache. By default Hibernate uses Ehcache as caching provider, however JBoss AS 6 and 7 use Infinispan as caching provider.
One difference with the first level cache is that it's not on by default but it needs some configuration in your persistence.xml to tell Hibernate to turn on the cache. The configuration differs depending on the version of JBoss AS used. Let's see each configuration in detail.
Using second level cache with JBoss AS 5
JBoss AS 5 uses JBoss Cache as caching provider. This is the configuration required to turn on the 2nd level cache on JBoss 5:
By setting the property hibernate.cache.use_second_level_cache to true we are turning on the second-level cache mechanism. The cache, by default, is activated only for entities, so we also need to explicitly set hibernate.cache.use_query_cache to true if we want to cache queries as well.
The second-level cache can be implemented using several different schemas—open source and commercial. In the next property, hibernate.cache.region.factory_class, we are telling Hibernate to use JBoss Cache as the second-level cache implementation.
The next parameter, hibernate.cache.region.jbc2.cachefactory, is specific to the JBoss Cache implementation. It specifies the JNDI name under which the CacheManager to be used is bound. There is no default value, thus the user must specify the property.
The hibernate.cache.region.jbc2.cfg.collection property is also specific to JBoss Cache and details the name of the configuration that should be used for collection caches (in our configuration, mvcc-entity).
Using second level cache with JBoss AS 6
JBoss AS 6 uses Infinispan 4 as cache provider. The required properties for persistence.xml follows here:
The relevant part of this configuration is the cache manager which is bound in the JNDI tree under the name java:CacheManager/entity
The JNDI name to which the hibernate cache container is bound is defined in infinispan-configs.xml:
Using second level cache with JBoss AS 7
JBoss AS 7 uses Infinispan 5 as caching provider. Here's the suggested configuration:
In JBoss 7 the Infinispan cache manager is bound under the java:jboss/infinispan/hibernate name and is configured into the standalone-ha.xml or domain.xml inside the infinispan subsystem:
Notice the JPA 2 shared-cache-mode element which is used to determine if the entity need to be cached or not. The shared-cache-mode element has four possible values:<
|ALL||Causes all entities and entity related state and data to be cached.|
|NONE||Causes caching to be disable for the persistence unit and all cahing is turned off for all entities|
|ENABLE_SELECTIVE||Enables the cache and causes entities for which Cacheable(true) is specified to be cached.|
|DISABLE_SELECTIVE||Enables the cache and causes all entities to be cached except those for which Cacheable(false) is specified|