11

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.

M Sach
  • 33,416
  • 76
  • 221
  • 314
  • You seem to be very confused here. These items are all part of the second level cache. If the second level cache is turned on **everything** (almost) goes through it. All sessions use the _same_ second level cache - this is why it's second level. Each session also has it's own cache (the first level cache if you will). – Boris the Spider May 04 '14 at 08:32
  • but whats the diff b/w second level and query cache? – M Sach May 04 '14 at 08:36
  • 1
    In your example you must put `@Cache` annotation on the employee entity itself cause collection cache holds nothing but employees primary keys (ids) and not actual employee instances. It means that Hibernate will have to go to DB to load them if employee itself is not cached also. – oceansize May 04 '14 at 09:22
  • @Boris the Spider Not everything (almost) at all but those entities only which are marked with jakarta.persistence.Cacheable or org.hibernate.annotations.Cache – Andrey M. Stepanov Apr 14 '23 at 02:05

3 Answers3

10

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

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • "The second level cache is meant for accessing the object by Primary Key, means the searching for whole entities based on Primary Key ie with session.get(), session.load() methods. I can think of only above two methods where second level cache will come in to picture."Is this statement correct? – M Sach May 04 '14 at 08:52
  • 1
    Say i have department(cacheable entity) which has collection of employees. How can i make employees cacheable also? – M Sach May 04 '14 at 08:54
8

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.

Mudit bhaintwal
  • 528
  • 1
  • 7
  • 21
1

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.

Ritesh Kaushik
  • 715
  • 2
  • 13
  • 24