First level Second level Cache Example Hibernate


Cache Hibernate Tutorial

Note: Use the same Student First Program. Just change the client program and modify the XML files and also add a new XML file ehcache.xml.

Now go on read Cache Hibernate.

We know, file reading with BufferedInputStream gives more performance (around 1500 times more) than FileInputStream. It is due to buffering effect. Same case with database accesses also. More the database hits, less the performance. To increase the database access performance, Hibernate comes with caching mechanism to give high performance.

Especially, in Web applications, performance is a bottleneck due to database traffic. Caching is the most preferred technique to solve this problem. Caching is nothing but some buffer where a record is stored when first time retrieved from the database. When second time needed the same record, Hibernate does not access the database and instead reads from the cache. This type of adjustment decreases the database hits. This is what Cache Hibernate is. Accessing cache is much faster than accessing the database.

Cache Hibernate implementations

Hibernate comes with two types of cache mechanism – First-level cache and Second-level cache.

1. First-level cache with Session Object

First-level cache is associated with Session object. It is the default cache Hibernate uses (where programmer need not write any extra code).

image

How it works? Hibernate does not process each database hit separately and instead preserves the query in the buffer memory (associated with Session). Infact, it writes one addBatch() statement and stores with the Session object. When the transaction is committed or session is flushed, Hibernate executes all the queries, stored earlier, with executeBatch() statement. This obviously increases the performance.

Session cache is useful on a per-transaction basis. What does it mean? Let us see clearly. As the first level cache is associated with the Session object, its scope is limited to one session only. If we fetch a record (better call as persistent object in Hibernate), say with get() method, from the database, it is stored with the Session cache. If the same record is fetched again second time, database hit is not made as it gets from the Session cache. This you can see in the Console screen in the coming programs. If you fetch the same record with another Session object, database hit is made.

2. Second-level cache with SessionFactory Object

Second-level cache always associates with the SessionFactory object. While running the transactions, whatever records (or persistent objects) the session object fetches from the database are preserved in SessionFactory cache (buffer). These records are available not only to the current Session object but all Session objects created from SessionFactory object. Any Session object requires the same record again, the database is not hit and instead reads from the SessionFactory cache. This we can prove later in the client program.

Cache Hibernate

The entire applications can access the SessionFactory cache. It is like ServletContext in case of servlets. If you would like the object data should be available to all the threads in the client program, the best choice is second-level cache.

Hibernate comes with four open-source cache implementations to support second-level caching.

1. EHCache (Easy Hibernate Cache)
2. OSCache (Open Symphony Cache)
3. Swarm Cache
4. JBoss Tree Cache.

Each style differs in their performance, memory usage and support for different properties supported by servers like clustering etc.

For this program of Cache Hibernate, we use EHCache. EHCache comes by default with Hibernate software.

Here we wrote two programs with first-level and second-level caching.

Let us use our First Program – Student.

1. First-level Cache

File Name: FirstLevelCache.java

import java.util.Iterator;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class FirstLevelCache 
{
  public static void main(String[] args) 
  {
    Configuration c = new Configuration();
    c.configure("/hibernate.cfg.xml");
    SessionFactory sf = c.buildSessionFactory();
		
    Session s1 = sf.openSession();
    Session s2 = sf.openSession();
	      
    Student std1 = (Student) s1.get(Student.class, new Integer(100));
    System.out.println(std1.getSid() + " " + std1.getSname() + " " + std1.getSmarks() + " " + std1.getSjoindate());

    Student std2 = (Student) s2.get(Student.class, new Integer(100));
    System.out.println(std2.getSid() + " " + std2.getSname() + " " + std2.getSmarks() + " " + std2.getSjoindate());
   }
}  

In the above program, two different Session objects, s1 and s2, are created and each object retrieves the same Student record of sid 100. As it is two different session objects, database is hit two times. You can observe this in the following Console screenshot.

Cache Hibernate

Now let us make a small change in the above program and watch. Here, the same Session object s1 retrieves two times the same record of 100 sid. Database is hit only once.

  Student std1 = (Student) s1.get(Student.class, new Integer(100));
  System.out.println(std1.getSid() + " " + std1.getSname() + " " + std1.getSmarks() + " " + std1.getSjoindate());

  Student std2 = (Student) s1.get(Student.class, new Integer(100));
  System.out.println(std2.getSid() + " " + std2.getSname() + " " + std2.getSmarks() + " " + std2.getSjoindate());

Observe the screenshot for the above code and watch only once database hit (query) is done.

image

2. Second-level Cache

File Name: SecondLevelCache.java

In second-level cache, we use two different session objects and still database hit is made only once. It requires minor changes in both XML files. One more requirement is a addition of a new XML file ehcache.xml .

import java.util.Iterator;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class SecondLevelCache 
{
  public static void main(String[] args) 
  {
    Configuration c = new Configuration();
    c.configure("/hibernate.cfg.xml");
    SessionFactory sf = c.buildSessionFactory();
		
    Session s1 = sf.openSession();
    Session s2 = sf.openSession();
	      
    try 
    {
      Student std1 = (Student) s1.get(Student.class, new Integer(100));
      System.out.println(std1.getSid() + " " + std1.getSname() + " " + std1.getSmarks() + " " + std1.getSjoindate());

      Student std2 = (Student) s2.get(Student.class, new Integer(100));
      System.out.println(std2.getSid() + " " + std2.getSname() + " " + std2.getSmarks() + " " + std2.getSjoindate());
    } 
    catch (Exception e) 
    {
      e.printStackTrace();
    }
  }
}  

Modifications to be done in both the XML files for second-level cache usage.

a) In cfg file add following lines just before resource mapping tag as follows.

   true
   org.hibernate.cache.EhCacheProvider
		
   

b) a) In hbm file add following line just after <class name="Studnet" ….> and just before <id name="sid" …> as follows:

  
  
  

Following is the screenshot of the Console where you can observe the database is hit only once (sql statement is executed only once).

Cache Hibernate

Let us discuss the contents of ehcache.xml file.


The above code of XML file is useful when the records retrieved goes in lakhs where the RAM is not sufficient to store them. Ehcache allows us to store all the records retrieved in hard disk.

maxElementsInMemory=”2″

The above statement informs the Hibernate to place 2 records (in Hibernate style, 2 objects) in RAM out of the many in the hard disk.

eternal=”false”

Eternal with false value indicates the records should not be stored in hard disk permanently.

timeToIdleSeconds=”120″

120 seconds, the records may live in RAM and afterwards they will be moved to hard disk.

timeToLiveSeconds=”300″

The maximum storage period in the hard disk will be 300 seconds and afterwards the records are permanently deleted from the hard disk (not from database table).

overflowToDisk=”true”

When the records retrieved are more than 2, the excess records may be stored in hard disk specified in the ehcahe.xml file.

Disk Cache program is given separately.

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class DiskLevelCachingClient 
{
  public static void main(String rags[]) throws Exception 
  {
    Configuration c = new Configuration();
    c.configure("/hibernate.cfg.xml");
    SessionFactory sf = c.buildSessionFactory();
    Session s = sf.openSession();
    Query q = s.createQuery("FROM Course");
    List list = q.list();
    Thread.sleep(1000*10);
    for(Course c1 : list)   
    {
      System.out.println(c1);
    }
  }
}

Possible directories where the records can be stored:

user.home: User’s home directory
user.dir: User’s current working directory
java.io.tmpdir: Default temp file path –>

The user.home, user.dir and java.io.tmpdir are the folders where the second-level cache records can be stored on the hard disk. The programmer should choose one.

Observe the following statement in the ehcache.xml file.

The above statement informs the records should be stored in user.dir folder.

In the Ehcache.xml file, the disk path is given as C:\snrao. In the disk, a file by name Course.dat data file is created in C:\snrao folder. Into this file, the oversized records (objects) are written. But data cannot be read as it is in serialized format.

7 thoughts on “First level Second level Cache Example Hibernate”

  1. Hello Sir
    can you check this page again because some pictures has not included any statement.
    Do we have to create ehcahe.xml in our project before creatingSecondLevelCache class?

    Thank you very much again for your tutorials
    R.Vithu

  2. I was recommended this websiote through my cousin. I am no
    longer positive whether or noot this put up iss written by him as
    no oone else know such distinct about my difficulty.
    You are amazing! Thanks!

Leave a Comment

Your email address will not be published.