Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Understanding the Hibernate Cache L1 and L2 in detail

In this article we will see how Hibernate caching system works in practice, along with L1 and L2 level caches.

Working with Cache can be a headache to some extent, when you do not understand exactly what is being done. A lot of times, to try to increase the productivity of a project and deliver it faster, you end up just copying the internet cache settings, even without understanding what they do and wherever they go.

The problem of working mechanically, without understanding what is being done is when problems occur and you do not even know where to start analysis.

This article will deal with a much discussed concept, but it also brings many doubts and eventually becomes complex when not understood correctly, the Hibernate Cache. We will study here two forms ofcache that Hibernate uses: Caches Level L1 and L2.

What is cache and why to use it?

Before we start explaining technical concepts about settings and behaviors of Caching in Hibernate, it is essential that you understand why you're doing this not simply because it is more "beautiful" or because everyone uses.

Being more general, the concept of Cache, in computing as a whole, came to increase the performance of tasks, reducing access to I/O (Input and Output devices, such as HD). The in-memory data cache (cache), prevents the processor to have to access the HD (Hard Disk) every time you need some information to perform calculations in ALU (Arithmetic Logic Unit), for example. After a while this data is removed from the cache for new entering (because the cache is not infinite, as we imagined). That's why when accessing for the first time a program on your operating system it takes much longer than the second time.

The concept of Cache in Hibernate is no exception to the rule. Hibernate performs Caching coming from database data to avoid unnecessary access to the database, because this access is much more expensive than accessing memory, since access to the database depends on several factors such as network availability, speed network traffic, search engine optimized in the database, etc. All this can make a simple query become a big headache.

The function of the cache on Hibernate is in the first instance accessing the database and retrieving the requested data and recording in Cache. At the second time that this direct access will be done the data is retrieved from the cache, which greatly increase application performance.

Hibernate Cache

We will now explain the operation of each of the caches from this section. It is important to know that to have a better understanding of the operation of the cache on Hibernate is necessary to understand the functioning of the life cycle of a Session, that is, as it is created, how long it stays "alive", what we have within it and etc. This is beyond the scope of this article.

L1 cache or First Level Cache

The L1 cache is connected directly to the Hibernate Session, ie the L1 cache runs throughout the lifecycle of the Session object, thus "born" and "die" with him. Because the L1 cache is internal to a Session object, it can not be accessed from other Sessions created by the Session Factory.

Figure 1 explains the operation of this flow.

Hibernate Cache L1

Figure 1. Hibernate Cache L1

Here we have four objects in Figure 1:

  • Database: Represents the database figure.
  • First-Level Cache: Represent the L1 cache of Hibernate.
  • Session Object: Represents the current session of Hibernate.
  • Client: Represents the Client will prompt requests.

Note that the client does not communicate with the L1 cache, you know only the existence of the Session and it communicates with the L1 cache. When the client requests a database object (via the Session), this first consultation always check if this object has already been loaded, thereby preventing access to the database, otherwise it will get it in the database and then store in the L1 cache, so the second time we try to return it, access to the database will be made.

Let's see an example of this through code snippet in Listing 1.

Listing 1. Example of L1 cache running

//(1) Open a Session in Hibernate
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();


//(2) Search for the department fo the first time
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());


//(3) Search the same department again
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
System.out.println(department.getName());


session.getTransaction().commit();
HibernateUtil.shutdown();


Output:


Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=?
Human Resource
Human Resource

We have here three important points that explain in more details the flow of Figure 1.

  1. In the first section a Session is open and the L1 cache also is already automatically activated for this new Session.
  2. In the second point is made the first search of the Department in the database and as this object has not yet been stored in the cache, a query is triggered in the database. You can see it through the log generated by Hibernate:
    select department0_.ID the ID0_0_, department0_.NAME the NAME0_0_ from DEPARTMENT department0_ where department0_.ID = ?.
  3. In the third and final point, we tried again to search for the same Department in the database, then the Session searches it in the L1 cache and as it has been stored there, it's just recovered without firing a new database query.

Remember that the L1 cache is not shared in different Sessions, ie the same object Department for SessionX is different for SessionY. Let's see an example in Listing 2.Listing 2. Example of L1 cache With 2 Sessions

 //(1) Open a Session
 Session session1 = HibernateUtil.getSessionFactory().openSession();
 session.beginTransaction();
 
 //(1) Open another Session, different from the first
 Session session2 = HibernateUtil.getSessionFactory().openSession();
 sessionTemp.beginTransaction();
 try
 {
	 //(2) Search for the department for the first time in SESSION 1
	 DepartmentEntity department = (DepartmentEntity) session1.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
	  
	 //(3) Search for the department again in SESSION 1
	 department = (DepartmentEntity) session1.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
	  
	 //(2) Search for the department for the first time in SESSION 2
	 department = (DepartmentEntity) session2.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
 }
 finally
 {
	 session1.getTransaction().commit();
	 HibernateUtil.shutdown();
	  
	 session2.getTransaction().commit();
	 HibernateUtil.shutdown();
 }
 
 Output:
 
 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

The above code demonstrates that in trying to search for the same object in a different Session, the database access is done because it does not exist in the L1 cache of this Session.

But what if you want to force an object to be searched directly in the database, even if it is cached, how to? The answer is quick: removing it from the L1 cache, so you force the Session to directly query the database.

Two methods are available in the Session object that can make this task: evict() and clear():

  • The evict removes only one object of the L1 cache, that is, imagine that you have within the L1 cache five objects of different types, but I wish only the object of type Department to be consulted directly in the database, then you would make a "evict" to this object, which would clean it of L1 cache and then would make a "load" again.
  • The clear removes all objects present in the L1 cache, that is, if you have five objects, the five will be removed, forcing the direct search on the database next time a load is performed. Let's see an example for clarity in Listing 3.

Listing 3. Using evict() and clear()

 Session session = HibernateUtil.getSessionFactory().openSession();
 session.beginTransaction();
 try
 {
	 // Search for the department for the first time
	 DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
	  
	 // Search for the department for the second time
	 department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
	  
	 // clean the department from cache l1
	 session.evict(department);
	 //session.clear();
	  
	 // Search for the department for the third time
	 department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1));
	 System.out.println(department.getName());
 }
 finally
 {
	 session.getTransaction().commit();
	 HibernateUtil.shutdown();
 }
		  
 Output:
		  
 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

Let's see now some important points that should be set on the L1 cache before we move on to the next article of Cache.

  • The L1 cache is enabled by default in Hibernate and you can not disable it.
  • The Session object always query the L1 cache before going to the database.
  • The L1 cache is associated with only a Session object, other objects can not "see it".
  • When a load is first executed, the query is done directly in the database, because the object does not exist in the cache.

Conclusion

This was only the first part of this article, you can read in the next one how to understand what is the Query Cache and its importance to the whole process of cache at Hibernate world. See you there.



Julio is a System analyst and enthusiast of Information Technology. He is currently a developer at iFactory Solutions company, working in the development of strategic systems, is also a JAVA instructor. He has knowledge and experi...

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login