Question

As per my understanding, Second level cache will be used when the objects are loaded using their primary key. This includes fetching of associations.I can think of only above session.get(), session.load methods where second level cache will come in to picture.

If association is collection or some other entity , how it can be cached ? For example :-

  @Cacheable
  public class Department{
   private List Employees;
   private DepatmentDetail detail ;

}

How can i make association Employees and detail cacheable ? I think i need to mention @cache above associations Employees and detail. But that didn't work?

when developer does department.getEmployees(), hibernate will internally fire the query i.e

 select * from employees where deptId =1;

Now if i use query cache where i explicitly make above query and fetch the results, query will be fired again to db. why query is fired again . I think this is related to how hibernate internally stores the result of second level cache and query cache(they may be stored in separate regions). If somebody can throw light on this aspect also, it will be great.

Was it helpful?

Solution

Have a look at below links where it is explained in details.

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. This is only useful for queries that are run frequently with the same parameters.

Second-level cache

Hibernate is compatible with several second-level cache providers. Any implementation can be used for second level cache.

Difference:

Query Cache's sole purpose is to cache the queries whereas Second Cache can be used to cache for other caches also.

Query cache is provided by Hibernate internally whereas for Second level cache you have to choose some external second level cache such as Infinispan, EHCache etc.

enter image description here

OTHER TIPS

Second level cache has hash table like structure internally to hold the data. The Key here will be the identifier of the entity and value will be dehydrated values of the entity. To get the data out of this L2 cache, you must have a Key i.e. identifier of the entity. So clearly you can use it with methods where you are fetching entity by id.

This scenario changes when you have query_cache also enabled with L2 cache. Query cache stores the query and it's corresponding resultset entities' ids. Now even if you are not fetching by id (using JPQL or HQL OR queryDsl), hibernate checks if the same query is fired earlier and if yes get the list of ids from the query cache. After that returns the entities from L2 cache corresponding to same ids.

We need to explicitly put @Cache(usage=CacheConcurrencyStrategy.<VALUE>) on the collections and @Cacheable on the corresponding collection class. There is a very good explanation on hibernate second level cache here.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top