Hibernate Caching

Hibernate offers three types of cache to reduce the number of database hits and speed up performance. They are:

  1. Level 1 cache
  2. Level 2 cache
  3. Query cache

1. Level 1 Cache

This cache is associated with a Hibernate Session and is mandatory. You don’t have to do anything special to turn on level 1 caching or to configure it.
The Hibernate Session exists (usually) for the duration of an execution thread, and in the web app world this typically means for the duration of a single HTTP request.
Entities loaded from the database are stored in the level 1 cache, and if the same object is requested subsequently within the same Hibernate Session, the object is retrieved from the cache rather than the database.

// First request - triggers a database SELECT of Student object with id = 500
Student s = (Student) session.load(Student.class, 500);

// Second request in same session for Student 500: object retrieved from cache
Student t = (Student) session.load(Student.class, 500);

2. Level 2 Cache

This cache is associated with a Hibernate Session Factory and is optional. In a web application, the Session Factory is typically instantiated when the web app starts up and lives until the web app is closed down. The factory is therefore shared by all users of the web app - and so the level 2 cache is also shared by all users.
The level 2 cache must be explicitly turned on in the application’s Hibernate configuration, and the objects to be handled by this cache are specified by configuration. The cache implementation is not provided by Hibernate; a third-party cache must be plugged in. We use EHcache as our implementation.
Unlike the level 1 cache, the entity objects themselves are not cached - instead, string representations of the objects are created and stored in the cache. The lookup-key for an entry in the level two cache is the object type (i.e. class name) and the primary key value.
Now, because the level 2 cache is shared by all users, we would run into concurrency issues in the cache if two users were updating the same object at the same time. For this reason, the level 2 cache should be used only for “read-mostly” data - data which changes very infrequently, and is essentially used in a read-only manner by the application. An example would be a list of US state codes and names, or more generally, data in some MITSIS validation tables.

3. Query Cache

This is a cache of HQL queries and a representation of the results of executing the query. It works in tandem with the level 2 cache. The identifying “key” for a query in this cache is the HQL string itself along with any bind variable values. The cached data stored for this key is a list of primary keys of all the objects returned by the query.
So it seems that the query cache would only be useful if a query is done frequently using the same bind variables, and the data returned by the query is not expected to change. It’s hard to see a real-world use where this cache would provide benefit.

  • No labels