Thursday, March 30, 2023

Difference between First and Second Level Cache in Hibernate [Answer]

If you have used Hibernate in past then you know that one of the strongest points of the Hibernate framework is caching, which can drastically improve the performance of the Java application's persistence layer if configured and used correctly. Hibernate provides caching at many levels e.g. first level cache at Session level, second-level cache at the SessionFactory level, and query cache to cache frequently executed SQL queries. The first level cache minimizes database access for the same object. For example, if you call the get() method to access Employee object with id = 1 from one session, it will go to the database and load the object into memory, but it will also cache the object in the first-level cache.

When you will call the get() method again for the same object from the same session, even after doing some updates on the object, it will return the object from the cache without accessing the database. You can confirm this from Hibernate's log file by observing how many queries are executed.

This is also one of the frequently asked Hibernate Interview Questions, so it will not only help to improve the performance of your Java application but also help you to do well in your next interview.

If you are new to Hibernate then I also suggest you go through a comprehensive online course like Master Hibernate and JPA with Spring Boot in 100 Steps course by Ranga Rao Karnam on Udemy. It's a great course to learn Hibernate and JPA with Spring Boot in a hands-on and practical manner. It's also very affordable and you can buy it for just $10 on Udemy flash sales.

This session-level cache greatly improves the performance of Java applications by minimizing database roundtrips and executing fewer queries. For example, if an object is modified several times within the same transaction, then Hibernate will only generate one SQL UPDATE statement at the end of the transaction, containing all the modifications.


But, since this cache is associated with the Session object, which is a short-lived object in Hibernate, as soon as you close the session, all the information held in the cache is lost. So, if you try to load the same object using the get() method, Hibernate will go to the database again and fetch the record.

This poses a significant performance challenge in an application where multiple sessions are used, but you don't need to worry. Hibernate provides another application-level cache, known as second-level cache, which can be shared among multiple sessions. This means a request for the same object will not go to the database even if it is executed from multiple sessions, the provided object is present in the second-level cache.

The second-level cache is maintained at the SessionFactory level, which is used to open sessions, hence every session is linked to SessionFactory. This cache is opposite to first level cache which is by default enabled in Hibernate, this one is by default disabled and you need to configure the second level cache in Hibernate configuration file to enable it.


The second-level cache is provided with the help of caching providers e.g. EhCache and OSCache. If you look at the cache package in Hibernate, you can see the implementation of Caching related interfaces by these providers. Depending upon which cache you want to use, you can configure them in the Hibernate configuration file.

Once configured, every request for an object will go to the second level cache if it is not found in the first level cache. It won't hit the database without consulting second-level cache, which means improved performance.

It's very important for a Java and Hibernate developer to know about Caching in Hibernate. It's not just important from the Interview point of view but also from the application development and performance improvement point of view.

You will often face performance-related challenges in a real-world application which contain millions of records, by correctly configuring Hibernate sessions and writing code which make use of caching, your Java application can float above water even in the case of a significant load.

If you want to learn more about Hibernate's performance, I suggest reading  I suggest reading High-Performance Java Persistence book by Vlad Mihalcea, one of the best and up-to-date resources on hibernate performance at the moment.



Difference between First and Second Level Cache in Hibernate

Now that we know what is first level and second level cache are in Hibernate, let's revise some key differences between them from the interview point of view.

1. Scope

The first level cache is associated with the Session Object, while the second-level cache is associated with the SessionFactory object. This means first-level cache's scope is limited to session-level while second-level cache's scope is at the application level.

Since the Session object is created on-demand from the SessionFactory and it's destroyed once the session is closed, the same query is run from two different sessions will hit the database twice if the second-level cache is not configured.

On the other hand, second-level cache remains available throughout the application's life cycle.

Difference between First and Second Level Cache in Hibernate [Answer]




2. Configuration

The first level cache is by default enabled in Hibernate, while the second level cache is optional. If you need it then you need to explicitly enable the second level cache on the Hibernate configuration file i.e. the hibernate.cfg.xml file.

You can use the hibernate.cache.provider_class and hibernate.cache.use_second_level_cache properties to enable the second level cache in Hibernate. The first one is the name of the class which implements Second level cache and could be different, depending upon which cache you use like EhCache or OSCache.

By default,  hibernate.cache.provider_class is set to org.hibernate.cache.NoCacheProvider class, which means the second-level cache is disabled. You can enable it by setting something like org.hibernate.cache.EhCacheProvider if you want to use EhCache as the second-level cache.

Here is a sample configuration to configure Second level cache with EhCache:
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</prop>

Don't forget to include hibernate-ehcache.jar into your classpath. This class comes from that JAR. You can also see Java Persistence with Hibernate, 2nd edition to learn more about other configuration options available to the second-level cache.

How to configure Second Level Cache in Hibernate



3. Availability

The first level cache is available only until the session is open, once the session is closed, the first level cache is destroyed. On the other hand, the second-level cache is available through the application's life-cycle, it is only destroyed and recreated when you restart your application.


4. Order

If an entity or object is loaded by calling the get() method then Hibernate first checked the first level cache, if it doesn't find the object then it goes to the second level cache if configured. If the object is not found then it finally goes to the database and returns the object, if there is no corresponding row in the table then it returns null.

When an object is loaded from the database is put on both second level and first-level cache, so that other session who request the same object can now get it from the second-level cache.

In case if the object is not found in the first level cache but found in the second level cache because some other sessions have loaded the object before then it is not only returned from the first level cache but also cached at the first level cache, so that next time if your code request the same object, it should be returned from 1st level cache rather than going to the 2nd level cache.

Difference between First and Second Level Cache in Hibernate


In general. When an object is pass to save(), update(), or saveOrUpdate() method and retrieved by load(), get(), list(), iterate(), or scroll() method, that object is added to the internal cache of the Session and when the flush() is subsequently called, the state of the object is synchronized with the database.

The second-level cache can also be configured on a per-class and per-collection basis, which means it can cache a class or a collection. You can use class-cache and collection-cache elements in hibernate.cfg.xml to specify which class or collection to cache at 2nd level cache. You should remember that second-level cache by default doesn't cache any entity until you configure it.

You can also use JPA Annotation @Cacheable to specify which entity is cacheable. and Hibernate annotations @Cache to specify caching strategy like CacheConcurrencyStrategies like READ_WRITE or READ_ONLY to tell Hibernate how the second level cache should behave.


That's all about the difference between first and second level cache in Hibernate. It's not just an ORM tool, hibernate is much more than that and in-built caching is one of the biggest benefits of using Hibernate to implement persistence of DAO layer in Hibernate. By correctly configuring second-level cache and writing code to leverage both first-level and second-level cache in Hibernate, you can get improved performance in Java applications.


Other Spring and Hibernate Articles you may like
  • The Java Developer RoadMap (guide)
  • Difference between get() and load() method in Hibernate? (answer)
  • Top 5 Courses to learn Microservices in Java (courses)
  • 5 Spring and Hibernate Training Courses for Java developers (online courses)
  • 2 Books to Learn Hibernate from scratch (books)
  • Top 5 Courses to learn Hibernate and JPA in depth (courses)
  • Top 5 Courses to learn Spring Data JPA in depth (spring data courses)
  • Difference between Spring Boot and Spring Cloud (answer)
  • Difference between save and persist in hibernate (answer)
  • Top 5 Courses to learn Hibernate and JPA in-depth (courses)
  • Top 5 Courses to Learn Spring Framework in-depth (courses)
  • 5 Books to Learn Spring Framework in-depth (books)
  • 15 Spring Boot Interview Questions for Java developers (questions)
  • Why Hibernate Entity class should not be final in Java? (answer)
  • 10 Hibernate Questions from Java Interviews (list)
  • 10 Advanced Spring Boot Courses for Java Developers (courses)

Thanks for reading this article, if you like this Hibernate caching article and the interview question then please share it with your friends and colleagues. If you have any questions or feedback then please drop a comment.

P. S. - And, if you are serious about improving your Hibernate and JPA skills then I also recommend you check out these Spring and Hibernate online courses on Udemy. It's a great course to learn Hibernate and JPA with Spring Boot in a hands-on and practical manner. It's also very affordable and you can buy it for just $10 on Udemy flash sales.

4 comments :

Sanjay said...

Nice introductory information about chacheing in hibernate. Thanks

Unknown said...

I've worked with hibernate for years but in my current position we don't use Spring. So we have to commit transactions through the hibernate api, which flushes the session. If we used Spring AOP I think we do not need to flush the sessions as often. Is this correct?

Anonymous said...

How does the cache behave when there are multiple apps writing to the db? Will it know to invalidate ab entity if it was updated by other service?

javin paul said...

@Anonymous, if multiple application is writing into the DB then second level cache may not be accurate. The whole idea is that any DB write will happen via hiberante, but if that is not the case and you are updating data using SQL scripts in backend, then values cached at second level cache will become stale.

Post a Comment