Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate First level Cache vs Query Cache

Is first level cache different from query cache in hibernate? I have seen articles mentioning about first level and query cache, so i am confused.

like image 606
java_geek Avatar asked Oct 22 '13 11:10

java_geek


People also ask

What is Level 1 cache in Hibernate?

First Level Cache: Hibernate first level cache is associated with the Session object. Hibernate first level cache is enabled by default and there is no way to disable it. However hibernate provides methods through which we can delete selected objects from the cache or clear the cache completely.

What is the difference between L1 and L2 cache Hibernate?

The main difference between the first level and second level cache in Hibernate is that the first level is maintained at the Session level and accessible only to the Session, while the second level cache is maintained at the SessionFactory level and available to all Sessions.

Which caching strategy offers better performance in Hibernate?

Hibernate caching improves the performance of the application by pooling the object in the cache. It is useful when we have to fetch the same data multiple times. There are mainly two types of caching: First Level Cache, and.

What is query level cache in Hibernate?

Query-level Cache Hibernate also implements a cache for query resultsets that integrates closely with the second-level cache. This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated.


2 Answers

Yes, are different things. Like Lee Chee Kiam says, First level cache is enabled by default and you can't disabled it. Basically it's where Hibernate put the fetched entities the first time so a second query of the same object doesn't instantiate a new object, even avoids the query if it's by ID. An example about this here.

//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

We could say that the First Level Cache is the Hibernate implementation of the IdentityMap pattern.

The Query Cache is strictly related to Entities and it draws an association between a search criteria and the Entities fulfilling that specific query filter (from here). A query cache only holds the raw results of the queries as primary keys, in hibernate speak, id's. It does not hold the actual hydrated objects.

How does the query cache work?

Suppose we have the following criteria query:

session.createCriteria(Person.class)
    .add( Restrictions.eq("firstName", "Joey")
    ).setCacheable(true);

The query cache looks conceptually like an hash map where the key is composed by the query text and the parameter values, and the value is a list of entity Id's that match the query

*----------------------------------------------------------*
|                       Query Cache                        |                     
|----------------------------------------------------------|
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] |
*----------------------------------------------------------*

So, the next time we execute the same criteria query, Hibernate will look at that hash map and resolve that the Persons with id 1 and 2 match the restrictions. In this case you would be avoiding the cost of the query (that in this case is almost zero but could be an expensive query with joins,etc) but you'd still be hitting the database for query the Persons (now by id what is very fast) for construct the Person objects. The query cache is frequently used with Second Level Cache, that requires a third part implementation like Ehcache or infinispan.

The second level cache stores the entity data, but NOT the entities themselves. The data is stored in a 'dehydrated' format which looks like a hash map where the key is the entity Id, and the value is a list of primitive values. Here is an example on how the contents of the second-level cache look:

*-----------------------------------------*
|          Person Data Cache              |
|-----------------------------------------|
| 1 -> [ "Joey" , "Q" , "Public" , null ] |
| 2 -> [ "Joey" , "D" , "Public" ,  1   ] |
| 3 -> [ "Sara" , "N" , "Public" ,  1   ] |
*-----------------------------------------*

So, the query cache will gives us the ids 1 and 2, then Hibernate will construct the objects with the raw data in the second level cache that corresponds to Persons with id 1 and 2.

The query cache and second level cache are for entities with many reads and little or zero updates. Because the well known problem of inconsistency in every type of cache. So Hibernate will need invalidate or refresh the cache (with replication included if you have a clustered cache). With many updates you will be constantly invalidating the cache and it will be doing more harm than good.

Some explanations are taked from this great post and you should read this good answer too.

like image 200
gabrielgiussi Avatar answered Oct 16 '22 07:10

gabrielgiussi


First level cache is enabled by default and is per session basis. Query cache is not enabled by default, is shared across multiple sessions and should always be used in conjunction with the second-level cache.

To enable query cache, the following properties should be used:

hibernate.cache.use_second_level_cache=true
hibernate.cache.use_query_cache=org.hibernate.cache.EhCacheProvider
hibernate.cache.use_query_cache=true
like image 20
Lee Chee Kiam Avatar answered Oct 16 '22 08:10

Lee Chee Kiam