Thursday, July 25, 2013

Hibernate Caching - Second Level Cache

First Level Cache of hibernate (Detailed in the last post) is more specific to Session. Second Level Cache is another level where the cache is maintained in different regions across the sessions. The second level cache is divided into four regions: entity, collection, query, and timestamp.
Entity and Collection regions cache data from entities and their relations. 
The Query cache caches the result set of the database against the query. 
The Timestamp cache keeps track of last updated time of each table.
There will be on timestamp cache enabled for each query cache. The following properties to be set to enable the second level caching
hibernate.cache.use_second_level_cache = true|false
hibernate.cache.use_query_cache = true|false
hibernate.cache.region.factory_class=net.sf.ehcache.hibernate.EhCacheRegionFactory
Since Hibernate4, the factory "org.hibernate.cache.ehcache.EhCacheRegionFactory" to be used instead of "net.sf.ehcache.hibernate.EhCacheRegionFactory"
In addition to above lines, the objects to be specified with the cache strategy. The line to be specified in the hibernate hbm file in <class> tag is
<cache usage="read-write|nonstrict-read-write|read-only" />
If to be specified in Annotations on the Entity Class, use
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
How it Works

  • When we fetch an object using hibernate, it searches the object in first level cache. If found, it returns the object
  • If the object not found in first level cache, checks the second level cache. If found, stores the object in first level cache returns
  • If the entity is not found both the levels, a database query is fired and stores in both the levels and returns.
  • The second level cache validates all of its entities, if any modifications are done through hibernate APIs. But, it never know if the database object is modified by any other resource unless "timeToLiveSeconds" duration has passed 

Notes:
To view the statistics of Entity fetches, second level cache hits, etc. We need to configure explicitly as.
hibernate.generate_statistics=true|false
and using "sessionFactory.getStatistics()" which retunrs an object of Statistics type.