Search This Blog

Friday, 16 August 2013

Hibernate Cache Framework

The Hibernate framework comes with a complete caching system. This cache system is used to reduce the amount of SQL queries fired in the system.
The Hibernate cache is built at two levels - a first level or session cache which we saw earlier and the second level cache. While the first level cache is non optional, the second level cache needs to be configured and switched on for use.
The first level cache works at a session scope. The second level cache on the other hand is associated with the sessionFactory. Thus it is possible for different sessions to find and use this cached data. In case of a clustered application we can have a cache that is used across multiple session factories.

 As can be seen above the Hibernate second level cache is built of multiple components.
  1. The class cache is used to cache instances of a class. The cache is used for a whole hierarchy of classes and not just a particular sub-class.
  2. Classes may have Collections within them and you would like to cache which entities are associated with a particular collection. For this the collections cache is used. For every collection that you need to be cached, you need to define a collection cache region.
  3. If we include cache settings in our mapping data, then the second level cache is automatically enabled. This is not the case with query cache. We need to explicitly enable it as a part of hibernate settings.
  4. The Query cache is a specialized cache that is used to cache the results of a query. The Query cache is not enabled by simply enabling the second level cache. To cache query results we need the following setting in our cfg files:  hibernate.cache.use_query_cache = true
  5. On enabling query caching, Hibernate sets up an additional cache holding timestamps of the most recent updates to tables against which queries are cached.
The Hibernate caching framework is flexible enough and allows us the choice of using our own Cache providers. It also provides built in support for some cache providers. I shall configure a second level cache using one of these providers - EhCache.
For this example I created three classes:
public class Book {
    private String name;
    private Integer id;
    private BookType bookType; // many books have one book Type
    private BookReleaseDetail releaseDetail; // This is a one to one relation

public class BookReleaseDetail {
    private Integer id;
    private Book book;
    private Date releaseDate;
    private String releasedBy;

public class BookType {
    private String name;
    private Set<String> descriptors = new LinkedHashSet<String>();
    private Integer id;
To setup the cache provider we need to make entries in our cfg file:
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
The first element is a global switch that tells Hibernate to switch on the second level caching support. The second tells Hibernate the name of the cache provider to use. If we need to disable the cache we set the value to false. You do not have to remove the caching configurations added to the class metadata.
The next step is to configure our entities to work with caching.