We used cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it. What For?

« Back to Blogs

Hibernate Second Level Cache Using Ehcache for cluster environment

Caching is all about application performance optimization and it sits between your application and the database to avoid the number of database hits as many as possible to give a better performance. I am going to show how we can use ehcache as hibernate second level entity cache in clustered environment.

 

Prerequisite: Knowledge of EHcache, JGroups and Jconsole.

 

In context of multiple application server, you need to replicate ehcache among them for consistency. Ehcache modules for the following replicated caching mechanisms are available:

  • RMI

  • JGroups

  • JMS

For more information go through https://www.ehcache.org/documentation/2.8/replication.

 

Here, I am going with JGroups UDP Multicast. Below are steps to configure Ehcache as  hibernate second level entity cache using Jgroups for cluster environment.

 

  1. Add following dependency in pom.xml.

 

<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache-core</artifactId>
	<version>2.6.9</version>
</dependency>

<dependency>
	<groupId>net.sf.ehcache</groupId>
	<artifactId>ehcache-jgroupsreplication</artifactId>
	<version>1.7</version>
</dependency>

<dependency>
	<groupId>org.jgroups</groupId>
	<artifactId>jgroups</artifactId>
	<version>3.5.0.Final</version>
</dependency>

 

  1. Second level cache is disabled by default in hibernate, so we would need to enable it and add some configurations as shown below to get it working.

 

<property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.SingletonEhCacheProvider"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.generate_statistics" value="true"/>
  1. Configure Hibernate Entities to use Second-Level Caching. We can do this using annotation as shown below.

@org.hibernate.annotations.Cache(usage = org.hibernate.annotations.CacheConcurrencyStrategy.READ_WRITE)

 

We can use following values for cache strategy:

 

  • READ_ONLY:

This sets the cache region as a read only cache, and this means it can be very performant as the cache doesn't have to worry about locking. If you try to modify any of these objects though, you will get an exception.

 

  • NONSTRICT_READ_WRITE:

This allows you to modify cacheable objects, but the cache provider doesn't need to implement a strict lock on the cache. This means there is a potential for stale objects (ie one transaction has modified an object, but another object picks up the old version of the object from the cache). Choose this for writable objects, but only if you don't care about stale data.

 

  • READ_WRITE:

The "safest" but least performant option. The cache provider will lock the cache when the object is updated, ensuring that all transactions will see the most up to date version.

 

  1. EHCache comes with some defaults out of the box when you configure caching. But you can create your own configuration. You can easily do this by providing a file name ehcache.xml on the classpath. Below is sample configuration ehcache.xml.

 

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true">
 
<diskStore path="../EhcacheData"/>
	
<cacheManagerPeerProviderFactory  class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
properties="connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;ip_ttl=32;
    mcast_send_buf_size=150000;mcast_recv_buf_size=80000):
    PING(timeout=2000;num_initial_members=6):
    MERGE2(min_interval=5000;max_interval=10000):
    FD_SOCK:VERIFY_SUSPECT(timeout=1500):
    pbcast.NAKACK(gc_lag=10;retransmit_timeout=3000):
    UNICAST(timeout=5000):
    pbcast.STABLE(desired_avg_gossip=20000):
    FRAG:
    pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;
    shun=false;print_local_addr=true)"
    propertySeparator=":"
	/>
<cache 
		name="com.st.model.Profile"
		maxElementsInMemory="500"
      		 eternal="false"
       		timeToIdleSeconds="120"
		timeToLiveSeconds="120"
		overflowToDisk="true"
		maxElementsOnDisk="500"
		diskPersistent="false"
		diskExpiryThreadIntervalSeconds="120"
		memoryStoreEvictionPolicy="LRU"
		statistics="true"
	>
	<cacheEventListenerFactory
            	class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
            	properties="replicateAsynchronously=true, replicatePuts=false,
            	replicateUpdates=true, replicateUpdatesViaCopy=false,
            	replicateRemovals=false" />
	</cache> 
</ehcache>

 

That’s It. Cache is configured…!!

Does your cache work?

When you have finally configured your cache, you want to know if it works. Of course you can check entities are cached or not, hit and miss ratio for them. You can export Mbean for that and see statistics in Jconsole for each entity you marked as cacheable.

contact-us Request a callback WhatsApp