Skip to main content

Hibernate Caching

Hibernate support two level cache.
1. First level cache.
2. Second level cache.

As we know that performance of hibernate is high because of First level
and second level cache in hibernate.

First level Cache

It is default behavior of hibernate and data available in cache for specific session.

i.e
Suppose in same session you fetch some data and after that if you will try again to
fetch same data then hibernate will give data from Cache.

Let’s understand with this Example

FirstlevelCache.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.spy.operation;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class FirstLevelcache
{
	public static void main(String[] args) 
	{
		SessionFactory sessionfactory=new Configuration().configure().buildSessionFactory();
		Session session=sessionfactory.openSession();
		session.beginTransaction();
 
		//getting user
		Userdata user=(Userdata)session.get(Userdata.class,5);
 
		//getting same user again it is already avaible in first level cache
		Userdata user2=(Userdata)session.get(Userdata.class,5);
		session.close();
   }
}

Output:

1
2
3
 
Hibernate: select userdata0_.id as id1_0_, userdata0_.user as user1_0_ from Userdata userdata0_ where userdata0_.id=?
What happen if we access data in different session?

Now if you access same data in different session then it will not give data from cache it run new query for it.
Solution: Second level cache but it’s not default you have to explicitly enable it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
package com.spy.operation;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class FirstlevelEx
{
	public static void main(String[] args)
	{
		SessionFactory sessionfactory=new Configuration().configure().buildSessionFactory();
		Session session=sessionfactory.openSession();
		session.beginTransaction();
 
		//getting user
		Userdata user=(Userdata)session.get(Userdata.class,5);
		session.getTransaction().commit();
		session.close();
 
		//creating new session
		Session session2=sessionfactory.openSession();
		session2.beginTransaction();
 
		//accessing data but it is not available in first level cache because we are in different //session
		Userdata user2=(Userdata)session2.get(Userdata.class,5);
		session2.getTransaction().commit();
		session2.close();
	}
}

Output:
you can see here hibernate fire two query while accessing same data in another session

1
2
3
 
Hibernate: select userdata0_.id as id1_0_, userdata0_.user as user1_0_ from Userdata userdata0_ where userdata0_.id=?
Hibernate: select userdata0_.id as id1_0_, userdata0_.user as user1_0_ from Userdata userdata0_ where userdata0_.id=?

Second level Cache

How to enable second level cache
Pre requirement:
Add ehcache jar file into hibernate library.

Hibernate.cgf.xml

1
2
3
4
 
<!-- enable the second-level cache -->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

Let’s Understand using Example

Hibernate.cfg.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
<session-factory>
 
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/test</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
 
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">10</property>
 
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
 
<!-- enable the second-level cache -->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
 
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="com.spy.data.Employee12"/>
<mapping class="com.spy.operation.Userdata"/>
 
</session-factory>
</hibernate-configuration>

Userdata.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
package com.spy.operation;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedNativeQuery;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.NamedQuery;
@Entity
@Cacheable
public class Userdata
{
	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	int id;
	String user;
 
	public int getId() 
	{
	 return id;
	}
	public void setId(int id) 
	{
	 this.id = id;
	}
	public String getUser()
	{
	 return user;
	}
	public void setUser(String user)
	{
	 this.user = user;
	}
}

Secondcache.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
package com.spy.operation;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class FirstlevelEx
{
	public static void main(String[] args) 
	{
		SessionFactory sessionfactory=new Configuration().configure().buildSessionFactory();
		Session session=sessionfactory.openSession();
		session.beginTransaction();
 
		//getting user
		Userdata user=(Userdata)session.get(Userdata.class,5);
		session.getTransaction().commit();
		session.close();
 
 
		Session session2=sessionfactory.openSession();
		session2.beginTransaction();
 
		//accessing data that are available in second level cache
		Userdata user2=(Userdata)session2.get(Userdata.class,5);
		session2.getTransaction().commit();
		session2.close();
}
}

Output:
Now you can see hibernate fire only one query

1
2
 
Hibernate: select userdata0_.id as id1_0_, userdata0_.user as user1_0_ from Userdata userdata0_ where userdata0_.id=?