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
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
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