Caching Objects in Hibernate

The caches are used to improve the performance of hibernate web applications by optimizing the database applications. The cache stores the already loaded data from the database. This helps to reduce the traffic between our application and database when the application wants to access that data again. Because the time needed to access the database is more when compared with the time needed to access the cache. The cache stores the data related to current running application. So the cache should be cleared time to time when the applications are changing. The cache is sits between your application and the database to avoid the number of database hits.

 Caching in Hibernate
Caching in Hibernate

Hibernate supports different types of caches for object.

  1. First level cache
  2. Second level cache
  3. Query level cache

First level cache

The first level cache is associates with the session object and this cache is used as default cache. The mechanism of this cache is it executes one transaction after other one. That is it never repeats one transaction in so many times and it reduces the number of SQL queries. The update process is happened only at the end of the transaction. The first cache type is the session cache. The session cache caches object within the current session. As already the session cache caches values within the current session.  This cache is enabled by default.

Eg: –

Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Person p where p.id=1");
Iterator it = query.list().iterator();
while (it.hasNext ()){
Person p = (Person) it.next();
System.out.println(p.getFirstName());
}
query = session.createQuery("from Person p where p.id=1");
it = query.list().iterator();
while (it.hasNext ()){
Person p = (Person) it.next();
System.out.println(p.getFirstName());
}
tx.commit();
session.close();

Second level cache

Second level cache is associates with the session factory object. In the transaction process it loads the objects at the session factory level. This helps to those objects will available to the entire application and it never bounds as a single user. We can also use query level cache in this level. The second level cache is responsible for caching objects across sessions. The second-level cache can be configured on a per-class and per-collection basis and mainly responsible for caching objects across sessions. An org.hibernate.cache.CacheProvider provide the hibernate with cache implementation mechanism. The set up of hibernate second level cache is done through two different ways.

1)      We decide which concurrency strategy to use

Concurrency strategy is a type of mediator which responsible for storing items of data in the cache and retrieving them from the cache. Hibernate support several concurrency strategies.

A)    Transactional

This strategy is used for read-mostly data where it is critical to restrict stale data in concurrent transactions, in the rare case of an update.

B)    Read – write

This strategy is also used for the same purpose of transactional strategy.

C)    Nonstrict – read – write

This strategy creates no guarantee of consistency between the cache and the database. This strategy is used when data hardly ever changes and a small likelihood of stale data is not of critical concern.

D)    Read only

This strategy is used for only data reference mechanism.

Eg: -Example of read – write concurrency strategy

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class table="EMPLOYEE">
<meta attribute="class-description">
This class contains the employee detail.
</meta>
<cache usage="read-write"/>
<id column="id">
<generator/>
</id>
<property column="first_name"/>
<property column="last_name" type="string"/>
<property column="salary" type="int"/>
</class>
</hibernate-mapping>

2)       Configure cache expiration and physical cache attributes using the cache provider.

Hibernate helps to choose a single cache provider for the whole application. The following are the different types of cache provider.

1)      EHCache: – It can cache in memory or on disk and clustered caching and it supports the optional Hibernate query result cache.

Features:-

a)      Fast

b)      Light weight

c)      Easy to use

d)     Support read only and read write caching

e)      Supports memory based and disk based caching

f)       Does not support clustering

2)      OSCache: – It supports caching to memory and disk in a single JVM, with a rich set of expiration policies and query cache support.

Features:-

a)      Powerful

b)      Flexible

c)      It supports read only and read write caching

d)     Supports memory- based and disk-based caching.

e)      It provides basic support for clustering via either JavaGroups or JMS

3)      warmCache: – A cluster cache based on JGroups. It uses clustered invalidation but doesn’t support the Hibernate query cache

Features:-

A)    It is a cluster-based caching

B)    It supports read-only or nonstrict read/write caching

C)    Appropriate for applications those have more read operations than write operations

4)      JBoss Cache: – A fully transactional replicated clustered cache also based on the JGroups multicast library. It supports replication or invalidation, synchronous or asynchronous communication, and optimistic and pessimistic locking. The Hibernate query cache is supported.

Features:-

a)      It  is a powerful replicated and transactional cache

b)      It useful when we need a true transaction-capable caching architecture

The below table describe the cache provider compatible with every concurrency strategy.

Strategy/Provider Read-only Nonstrictread-write Read-write Transactional
EHCache X X X
OSCache X X X
SwarmCache X X
JBoss Cache X X

Query level cache

Query level cache 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 and also  useful for queries that are run frequently with the same parameters. Hibernate provide a cache for query resultsets that integrates closely with the second level cache.