Understanding hibernate first level cache with example

Caching is a facility provided by ORM frameworks which help users to get fast running web application, while help framework itself to reduce number of queries made to database in a single transaction. Hibernate achieves the second goal by implementing first level cache.

Fist level cache in hibernate is enabled by default and you do not need to do anything to get this functionality working. In fact, you can not disable it even forcefully.

Its easy to understand the first level cache if we understand the fact that it is associated with Session object. As we know session object is created on demand from session factory and it is lost, once the session is closed. Similarly, first level cache associated with session object is available only till session object is live. It is available to session object only and is not accessible to any other session object in any other part of application.

Hibernate first level cache

Hibernate first level cache

Important facts

  1. First level cache is associated with “session” object and other session objects in application can not see it.
  2. The scope of cache objects is of session. Once session is closed, cached objects are gone forever.
  3. First level cache is enabled by default and you can not disable it.
  4. When we query an entity first time, it is retrieved from database and stored in first level cache associated with hibernate session.
  5. If we query same object again with same session object, it will be loaded from cache and no sql query will be executed.
  6. The loaded entity can be removed from session using evict() method. The next loading of this entity will again make a database call if it has been removed using evict() method.
  7. The whole session cache can be removed using clear() method. It will remove all the entities stored in cache.

Lets verify above facts using examples.

First level cache retrieval example

In this example, I am retrieving DepartmentEntity object from database using hibernate session. I will retrieve it 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();

Output:

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 that second “session.load()” statement does not execute select query again and load the department entity directly.

First level cache retrieval example with new session

With new session, entity is fetched from database again irrespective of it is already present in any other session in 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();
}

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

You 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”.

Removing cache objects from first level cache example

Though we can not disable the first level cache in hibernate, but we can certainly remove some of objects from it when needed. This is done using two methods :

  • evict()
  • clear()

Here evict() is used to remove a particular object from cache associated with session, and clear() method is used to remove all cached objects associated with session. So they 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();
}
		
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

Clearly, evict() method removed the department object from cache so that it was fetched again from database.

Hope you likes above article. If you got any question or suggestion, drop a comment.

Happy Learning !!

Lokesh

I have 7 Years of rich experience in java technology. This has only increased my hunger to learn more. In this blog, i will be writing on different topics occasionally, and would love to engage in some meaningful serious discussions with you folks.

You may also like...

57 Responses

  1. Aparna says:

    Good explaination …

  2. anji says:

    Excellent… If you know second level cache also, can u please explain?

  3. Anuj Saxena says:

    HI Lokesh
    Can we update the first level cache

    • Lokesh says:

      No, it’s maintained by hibernate only. Still you can take help of evict() and refresh() methods to cleanup/refresh any particular entity inside first level cache.

  4. Anuj Saxena says:

    Example is good, many doubt has cleared regarding cache.

  5. Rasmi says:

    Beautifully explained thank u…………..

  6. venkata says:

    Thanks for your brief explanation on this.However I had a doubt on how this can be useful in real time scenario where I have 2 controllers and in each controller , it is hitting the database through opening the new session object,getting the results and immediately closing the session since it not possible to open the session until second controller results. So in those scenarios where it using the First Level Cache not hitting the database for second controller.

    • Lokesh says:

      What’s doubt?

      • venkata says:

        How to use First Level cache if we need to hit the database for same data from more than one place in application. for example in application I have 10 pages, 1st page, I hit the database and while retrieving the results from database by default it stored it in cache with in that session.

        Again, I need to use same data in 5th page, how can I retrieve data from cache instead of database since it will open another session

      • venkata says:

        In My application, I have 10 pages and in 1st page I hit the database and retrieve the results directly from database and this time it used first level cache by default.

        Again I need to use same data in 5th page, how can I use from cache instead of database.

  7. Selvakumar says:

    Good explanaion to understand the First Level Cache .

  8. thiago says:

    Thank you very much. WIth your explanation I being able to resolve my issue, but, I used SessionFactory.openStatelessSession() to get a “fresh” entity.

  9. Puneet says:

    Hi Lokesh, I m stuck in 1 issue,
    i m goin to delete multiple object in dao like ..

    sf.getCurrentSession.delete(object1);
    sf.getCurrentSession.delete(object2);
    sf.getCurrentSession.delete(object3);

    And getting following exception :
    org.hibernate.nonuniqueobjectexception a different object with the same identifier

    Pls help in resolving the issue.

    • Lokesh says:

      Can you please share the code is possible. That will be much better. Without code it’s very hard to guess.

      Basically, what hibernate is saying is that you have two objects which have the same identifier (same primary key) but they are not the same object.

  10. Prethesh Kumar Bhalotia says:

    Very nice articles on First Level Cache for Beginners. Thanks a lot for that.

  11. Dibyendu says:

    This is simply great.You have explained so nicely and cleanly.

  12. shrawan says:

    good explanation.

  13. Subhashini says:

    Nice explanation…thank u..

  14. LOKESh says:

    If object entity is in cache ,, how ot will get update if any chages is done in backend ??

  15. NagarajReddy says:

    Good expalnation… helped me a lot ..Thanks a lot :)

  16. Bharat Shivram says:

    Nicely explained. Thanks

  17. pankaj kumar says:

    great concept

  18. upen says:

    thank u very much guptha your explanation was very good.plz post many topics

  19. Ravikiran Pise says:

    Excellent and Simple Explaination. Thanks for posting . Keep it up.

  20. Raghav says:

    Thanks Lokesh for a very simple and clear explanation.

  21. Swati says:

    Thank u so much. Its really very nice description along with the diagrams. Very nice to handle the interviews as well. Keep posting ..

  22. Guddu says:

    For What purpose we are using first level chache or second level chache.
    reply my answer
    thanks in advance

  23. yuvraj says:

    Nice example, thanks

  24. ayoub says:

    awesome

  25. sudheer says:

    Sudheer
    Vey nice explanation

  26. ssv says:

    you made it look so simple..:)
    thanks

  27. Rahul Gupta says:

    Thanks.. very nice explanation !!!!!!
    Really helped me to brushup the caching concept.

  28. venkatramireddy says:

    Thanks.. nice explanation !!!!!!
    Really helped me to understand caching .

  29. Gaurav says:

    Very Nice

  30. Sai says:

    Very thankful for your post. I struggled for months but cleared in minutes.

  31. Lalitha says:

    Nice Explanation. Thanks a lot for ur gr8 effort.

  32. Rishi says:

    Very nice explanation

  33. Shailesh says:

    Keep it up. Thanks for sharing.

  34. krishna says:

    Thanks sir, very nice and easly understandable

  35. Damo says:

    Nice explanation

  36. denizoguz says:

    Good explanation, thanks

  37. Amit Kumar says:

    excellent understanding with this example…..

  38. zd333 says:

    Like to learn more on the updating/deleting entities combined with the first level cache behavior. When the cache get updated vs when the query executed on the database.

  39. Shubhi says:

    Lovely tutorial. Loved every bit of it.

  40. pulkit says:

    Diagram,Explanation and example all are very good

  41. mateen27 says:

    waiting for second level cache demo…

  42. sarita says:

    Nicely explained..Whatever topics you have covered those are very helpful during the interview..Keep posting…and thanks a lot for your effort…

  43. Subrat says:

    Nice explanation.Keep it up

    • D.R. KANTH says:

      Example is good, but every where you copied same out put. If you use evict() 0r clear() it should display three select queries in output.

Note:- In comment box, please put your code inside [java] ... [/java] OR [xml] ... [/xml] tags otherwise it may not appear/post as intended.


Want to ask any question? Or suggest anything?