Caching is a facility provided by ORM frameworks that helps the users to get fast-running web applications while helping the framework itself to reduce the number of queries made to the database in a single transaction. Hibernate achieves the second goal by implementing the first-level cache.
1. Available Only through Session Object
First level cache in hibernate is enabled by default and we do not need to do anything to get this functionality working. In fact, we can not disable it even forcefully.
It is easy to understand the first level cache if we understand the fact that it is associated with Session
object. As we know the Session object is created on-demand from SessionFactory and it is lost, once the current session is closed. Similarly, the first-level cache associated with the Session object is available only till the session object is live.
The first-level cache is available to Session object only and is not accessible to any other session object in any other part of the application.

2. Facts About First-Level Cache
- The first-level cache is associated with a specific “session” object and other session objects in the application can not see it.
- The scope of cache objects is of the session. Once the session is closed, cached objects are gone forever.
- The first-level cache is enabled by default and we can not disable it.
- When we query an entity the first time, it is retrieved from the database and stored in the first-level cache associated with hibernate session.
- If we query the same entity again with the same session object, it will be loaded from the cache and no SQL query will be executed.
- The loaded entity can be removed from the session using
evict()
method. The next loading of this entity will again make a database call if it has been removed using evict() method. - The whole session cache can be removed using
clear()
method. It will remove all the entities stored in the cache.
Let us verify the above facts using examples.
3. Demo
3.1. Retrieve Entity in Same Session
In this example, I am retrieving DepartmentEntity from the database using a hibernate session. I will retrieve the entity multiple times and will observe the SQL logs to see the differences.
//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
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
session.getTransaction().commit();
HibernateUtil.shutdown();
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
As you can see the second “session.load()” statement does not execute SELECT query again and loads the department entity directly from the cache.
3.2. Retrieve Entity in Different Session
With a new Session, the entity is fetched from the database again irrespective of whether it is already present in any other Session in the application.
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Session sessionTemp = HibernateUtil.getSessionFactory().openSession();
sessionTemp.beginTransaction();
try
{
//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
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
department = (DepartmentEntity) sessionTemp.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
}
finally
{
session.getTransaction().commit();
HibernateUtil.shutdown();
sessionTemp.getTransaction().commit();
HibernateUtil.shutdown();
}
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
We can see that even if the department entity was stored in “session” object, still another database query was executed when we use another session object “sessionTemp”.
3.3. Removing Cached Entity from First-level Cache
Though we can not disable the first-level cache in hibernate, we can certainly remove some objects from it when needed. This is done using two methods :
- evict(): removes a particular object from cache associated with the session
- clear(): remove all cached objects associated with the session
So these methods are essentially like remove one and remove all.
//Open the hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
try
{
//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
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
session.evict(department);
//session.clear();
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());
}
finally
{
session.getTransaction().commit();
HibernateUtil.shutdown();
}
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource
Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Happy Learning !!
Comments