Hibernate Caching

Posted By : Rohit Kumar | 03-May-2022

Hibernate caching acts as a layer between the particular database and your application. It reduces the time taken to get the specified data — because it fetches from memory rather than directly hitting the database. it's very useful after you have to fetch the identical reasonably data multiple times.

There are mainly two types of caching:

  • First level cache
  • Second-level cache

1). First level cache

The First level cache is by default enabled by Hibernate itself. The session object maintains the first-level cache.
An application can have many sessions. Data hold by one session object isn't accessible to the whole application — means the info of a specific session isn't shared with other sessions of the appliance. So you'll use the first-level cache to store local data i.e. required by the session itself.

let’s make it simple to grasp, As we all know that hibernate is an ORM tool that's wont to simplify DB operations. It “converts objects to relations (to store into DB) and vice-versa”.
So after you query an entity or object, for the very first time it's retrieved from the database and stored into the first-level cache (associated with the hibernate session). If we query for the identical entity or object again with the identical session object, it'll be loaded from cache and no SQL query are executed. Take a glance at the below code snippet

// We have one record in DB with the Employee details like, 101, John Doe, UK

// Open hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

// Fetch an Employee entity from the database very first time
Employee employee = (Employee) session.load(Employee.class, empId);
System.out.println("First call output : " + employee.getName());
 
// Request for Employee entity again
employee = (Employee) session.load(Employee.class, empId);
System.out.println("Second call output : "employee.getName());
 
session.getTransaction().commit();
HibernateUtil.shutdown();
 
// Output:
// First call output : 
// Second call output :

 

In the above example hibernate will fire query only one time to the Database. From the second time onwards it'll return only from the session object.

Some useful methods:

  • Session.evict(): to remove the cached/stored entity.
  • refresh(): method to refresh the cache.
  • clear(): method to remove all the entities from the cache.

 2) Second level cache

The second-level cache is by default disabled, the developer has to enable it explicitly, and therefore the SessionFactory object is responsible to take care of it. The second-level cache is accessible by the complete application means data hold by SessionFactory is accessible to any or all the sessions. detain mind that, once the session factory is closed all the cache related to that's also far from the memory.
Let’s take an example: Suppose your application has 2 active sessions session1 and session2 respectively. Now, session1 has requested data having id=101 in order that are going to be fetched from a database because it is that the first call, then it's stored into the second-level (SessionFactory) yet as within the first-level (session) cache also. Now, session2 requires the identical data so it's also been queried with the identical id=101. So this point session2 will get data from the SessionFactory, it'll not visiting hit the database. Take a glance at the below code snippet.

// Open hibernate session
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();

// Employee entity is fecthed very first time (It will be cached in both first-level and second-level cache)
Employee employee = (Employee) session.load(Employee.class, empId);
System.out.println(employee.getName());

// Fetch the employee entity again
employee = (Employee) session.load(Employee.class, empId);
System.out.println(employee.getName()); //It will return from the first-level

// Evict from first level cache (That will remove employee object from first-level cache)
session.evict(employee);

// Fetch same entity again using same session
employee = (Employee) session.load(Employee.class, empId);
System.out.println(employee.getName()); //It will return from the second-level

// Fetch same entity again using another session
employee = (Employee) anotherSession.load(Employee.class, empId);
System.out.println(employee.getName());//It will return from the second-level

System.out.println("Response from the first-level : " + HibernateUtil.getSessionFactory().getStatistics().getEntityFetchCount());
System.out.println("Response from the second-level : " + HibernateUtil.getSessionFactory().getStatistics().getSecondLevelCacheHitCount());
 
// Output:
// Response from the first-level : 1
// Response from the second-level : 2

 

 

About Author

Author Image
Rohit Kumar

Rohit Kumar is working as a Java Developer. He is proficient in Java, Sql, Mysql, Spring Core , Spring Boot and also have good Working knowledge in HTML, CSS ,JavaScript and Data Structure . He is a Quick Learner and He is always excited to learn new tech

Request for Proposal

Name is required

Comment is required

Sending message..