Hibernate second level cache are important for performance perspective. A second level cache is a process specific cache and is shared by all the individual session running in different threads. The data points which are good candidates for caching are:
To enable the cahce first we need to enable some properties in configuration. I am showing an example for properties as in Spring environment but same can be adapted for any other environment like as in persistence.xml
In Spring:
<!-- Enabling second level cache for hibernate -->
<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.region.factory_class">net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory</prop -->
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache.xml</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
In persistence.xml
<!-- Enabling second level cache for hibernate -->
<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
<!-- prop key="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory/ -->
<!-- prop key="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory/ -->
<property name="hibernate.cache.provider_configuration_file_resource_path" value="ehcache.xml" />
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.cache.use_second_level_cache " value="true"/>
Note the commented secion of cache provider. The commented secion is as per EhCache document but I could not get it work.
After that a configuration XML need to be provided in the classpath, which in this example is ehcache.xml. A sample ehcache.xml looks like
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<!-- Required elements -->
<diskStore path="java.io.tmpdir" />
<defaultCache maxElementsInMemory="25000" eternal="false"
timeToIdleSeconds="300" timeToLiveSeconds="300" overflowToDisk="true"
diskPersistent="false" diskExpiryThreadIntervalSeconds="300"
memoryStoreEvictionPolicy="LRU" />
<cache name="com.lalit.domain.Role" eternal="true"
maxElementsInMemory="10" />
</ehcache>
Here we are hooking Role object to be put in cache. The eternal is true as we do not expect role object to ever change so we can keep it always in cache. This might change based on your requirements.
Now the last part is to tell the Role object that it needs to participate in cache. For that
@Entity
@Table(name = "app_roles")
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Role{
You might want to change your CacheConcurrencyStretegy based on your need. To make sure that the Cache is working fine, run the app with hibernate logging level at DEBUG. And you should be able to see logging statements like "Cache hit".
Happy caching.
Comments
good info
Hi Lalith,
Good info. The page would look great if you install syntax highlighter - www.alexgorbatchev.com
tx
jj
Add new comment