Monday, December 31, 2007

Hibernate second level cache

Second level cache(2LC) of hibernate boosts the performance of websites.
One needs to be careful to handle the cache refresh.
By default hibernate 3 comes with EHcache for session level
cache(primary cache).
EhCache can also be used for secondary level cache.


Setup of 2LC using EHcache:

1. Setup the session factory with the below details:
hibernate.cache.provider_class as org.hibernate.cache.EhCacheProvider
hibernate.cache.use_query_cache as true

Optionally cache statistics can be enabled by using below

   hibernate.generate_statistics as true
   hibernate.cache.use_structured_entries as true


2. In the hbm files just under the class element put the below:
   cache region="com.xmp.web2.model.Article" usage="read-only"

   --in the above, the region is used to identify as cache key.

3. For query cache, set the Query as cacheable programatically.

   Query queryObj = session.createQuery(query);
   queryObj.setCacheable(true);

   -- This will cache all the query result, thus reducing DB hits.

4. To refresh a query programatically, do the below:
   --  sessionFactory.evict(Article.class, id);    //this will remove from the cache the article object instance with the primary key id. Note that the id is serializable and the type should be the same as defined in hbm.

5. To optionally print the statistics, enable statistic monitoring as told in step 1 and use the below:

static void printCacheStatistics(String regionName) {
 Statistics statistics = sessionFactory.getStatistics();
 SecondLevelCacheStatistics secondLevelCacheStatistics = statistics.getSecondLevelCacheStatistics(regionName);             
 System.out.println("2nd level CACHE Statistics :"+secondLevelCacheStatistics.toString());
}

To check cache statistics use the JSP as below:
<%@ page language="java" import="org.springframework.web.context.*,org.springframework.web.context.support.*,org.hibernate.*,org.hibernate.stat.*"%>

<%
String cacheRegion="com.xmp.web2.model.Article";

WebApplicationContext ctx =
 WebApplicationContextUtils.getRequiredWebApplicationContext(
  this.getServletContext());
SessionFactory sessionFactory = (SessionFactory) ctx.getBean("sessionFactory");
out.print(sessionFactory);
Statistics statistics = sessionFactory.getStatistics();
SecondLevelCacheStatistics secondLevelCacheStatistics = statistics.getSecondLevelCacheStatistics(cacheRegion);
out.print("<br/>");
out.println("Query cache hit count :"+statistics.getQueryCacheHitCount());
out.print("<br/>");
out.print("<br/>");
out.println("2nd level CACHE Statistics :" + secondLevelCacheStatistics.toString());

%>

Reference:
http://doc.javanb.com/hibernate-reference-3-2-4-ga-en/performance.html
http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache

An excellent write-up on 2ndLC http://tech.puredanger.com/2009/07/10/hibernate-query-cache/

1 comment:

Anonymous said...

I congratulate, it is simply excellent idea