Hibernate OSCache Configuration Example Tutorial

OSCache is a Java framework developed by OpenSymphony that makes it easy to cache content in Web applications. With hibernate, it can be configured to act as second level cache.

In my previous post, we learned about configuring EhCache with hibernate, which is default second level cache in hibernate. In this post, I am taking the example of configuring OSCache with hibernate.

Sections in this post:

Runtime dependencies
Hibernate configuration
In memory cache example
Physical cache example

Runtime dependencies

I have used Maven to manage the project dependencies, and the necessary additions in pom.xml files are:

<repositories>
	<repository>
	  <id>repository.jboss.org-public</id>
	  <name>JBoss.org Maven repository</name>
	  <url>https://repository.jboss.org/nexus/content/groups/public/</url>
	</repository>  
</repositories>

<!-- OSCache dependencies -->
<dependency>
	<groupId>opensymphony</groupId>
	<artifactId>oscache</artifactId>
	<version>2.4.1</version>
</dependency>
<dependency>
  <groupId>javax.jms</groupId>
  <artifactId>jms</artifactId>
  <version>1.1</version>
</dependency>

If you are not using maven then add corresponding jar files in your project build path.

Hibernate configuration

The only change for having OSCache configured in your project, you have to make in your hibernate configuration file hibernate.cfg.xml file:

	<!-- Cache provider class -->
	<property name="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

In memory cache example

This is default implementation and you will get it if not configured the physical cache properties. Let’s see the example test code:

	try
	{
		//Open the hibernate session
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
		
		//fetch the department entity from database first time
		DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		//fetch the department entity again; Fetched from first level cache
		department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		//Let's close the session
		session.getTransaction().commit();
		session.close();
		
		//Try to get department in new session
		Session anotherSession = HibernateUtil.getSessionFactory().openSession();
		anotherSession.beginTransaction();
		
		//Here entity is already in second level cache so no database query will be hit
		department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		anotherSession.getTransaction().commit();
		anotherSession.close();
	}
	finally
	{
		System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1
		System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1
		
		HibernateUtil.shutdown();
	}
	
	Output in console:
	
	Hibernate: insert into DEPARTMENT (NAME) values (?)
	Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
	Human Resource
	Human Resource
	Human Resource
	1
	1

You will get this output again and again because everytime hibernate is shut down, memory is flushed and second level cache is built on next run again.

Physical cache example

If you have a very large cache to build then it is good idea to build it in file system (e.g. C drive in windows). It will prevent the hibernate to build the cache on every time application is restarted. Also, second level cache fetch rules still applies.

To enable physical cache, download the oscache.properties file and uncomment following lines:

cache.memory=false
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.path=c:/temp/cache
cache.algorithm=com.opensymphony.oscache.base.algorithm.LRUCache

Let’s see the example test code:

	try
	{
		//Open the hibernate session
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
		
		//fetch the department entity from database first time
		DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		//fetch the department entity again; Fetched from first level cache
		department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		//Let's close the session
		session.getTransaction().commit();
		session.close();
		
		//Try to get department in new session
		Session anotherSession = HibernateUtil.getSessionFactory().openSession();
		anotherSession.beginTransaction();
		
		//Here entity is already in second level cache so no database query will be hit
		department = (DepartmentEntity) anotherSession.load(DepartmentEntity.class, new Integer(1));
		System.out.println(department.getName());
		
		anotherSession.getTransaction().commit();
		anotherSession.close();
	}
	finally
	{
		System.out.println(HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount()); //Prints 1
		System.out.println(HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount()); //Prints 1
		
		HibernateUtil.shutdown();
	}
	
	Output in console:
	
	Hibernate: insert into DEPARTMENT (NAME) values (?)
	Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
	Human Resource
	Human Resource
	Human Resource
	1
	1

Above code will create physical cache in location “c:tempcache“.

physical oscache example

Next time you run the example code again, you will get following output:

	Hibernate: insert into DEPARTMENT (NAME) values (?)
	Human Resource
	Human Resource
	Human Resource
	0
	2

Reason is simple that department entity is stored in physical second level cache and fetched from there. So hibernate will not go to database again.

To download the sourcecode of this project, follow given link.

Sourcecode download

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

5 thoughts on “Hibernate OSCache Configuration Example Tutorial”

    • No. They are persistent. When you restart your application, you need not to create them again. You can directly start searching in cache.

      Look at second run output in “Physical cache example” section, even we re-run the application and a new hibernate session factory was created, no database hit was there, and you got the department entity from physical cache itself.

      Reply
    • In “real time” applications, when you need to show archive/old data which is in N GB in size, physical cache MUST be used. You can not put load in database for such a huge data, also when thousands users are logged in application all the time.

      For example, in a document management system, after a couple of years you will have millions of document records in database. When any user want to view his documents, you can not afford to hit the database as it will virtually kill the database.

      Solution is physical cache implementations. They don’t hit database and are really super fast.

      Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.