Hibernate Second Level Cache

Hibernate second level cache uses a common cache for all the session object of a session factory.

Hibernate Second Level Cache

Hibernate Second Level Cache

Hibernate second level cache uses a common cache for all the session object of a session factory. It is useful if you have multiple session objects from a session factory.

SessionFactory holds the second level cache data. It is global for all the session objects and not enabled by default.

Different vendors have provided the implementation of Second Level Cache.

  1. EH Cache
  2. OS Cache
  3. Swarm Cache
  4. JBoss Cache

Each implementation provides different cache usage functionality. There are four ways to use second level cache.

  1. read-only: caching will work for read only operation.
  2. nonstrict-read-write: caching will work for read and write but one at a time.
  3. read-write: caching will work for read and write, can be used simultaneously.
  4. transactional: caching will work for transaction.

The cache-usage property can be applied to class or collection level in hbm.xml file. The example to define cache usage is given below:

  1. <cache usage="read-only" />  

Let's see the second level cache implementation and cache usage.

Implementation read-only nonstrict-read-write read-write transactional
EH Cache Yes Yes Yes No
OS Cache Yes Yes Yes No
Swarm Cache Yes Yes No No
JBoss Cache No No No Yes

Hibernate Second Level Cache Example

To understand the second level cache through example, we need to follow the following steps:

  1. Create a persistent class using Maven
  2. Add project information and configuration in pom.xml file
  3. Create the Configuration file
  4. Create a class that retrieves the persistent object.

Here, we are assuming, there is an emp1012 table in the oracle database containing some records.

1) Create a persistent class using Maven.

File: Employee.java
  1. package com.tpoint;    
  2. import javax.persistence.*;  
  3. import org.hibernate.annotations.Cache;  
  4. import org.hibernate.annotations.CacheConcurrencyStrategy;  
  5. @Entity  
  6. @Table(name="emp1012")  
  7. @Cacheable  
  8. @Cache(usage=CacheConcurrencyStrategy.READ_ONLY)  
  9. public class Employee {    
  10.     @Id  
  11. private int id;    
  12. private String name;    
  13. private float salary;    
  14.     
  15. public Employee() {}    
  16. public Employee(String name, float salary) {    
  17.     super();    
  18.     this.name = name;    
  19.     this.salary = salary;    
  20. }  
  21. public int getId() {  
  22.     return id;  
  23. }  
  24. public void setId(int id) {  
  25.     this.id = id;  
  26. }  
  27. public String getName() {  
  28.     return name;  
  29. }  
  30. public void setName(String name) {  
  31.     this.name = name;  
  32. }  
  33. public float getSalary() {  
  34.     return salary;  
  35. }  
  36. public void setSalary(float salary) {  
  37.     this.salary = salary;  
  38. }    
  39. }    

2) Add project information and configuration in pom.xml file.

Open pom.xml file and click source. Now, add the below dependencies between <dependencies>....</dependencies> tag.

  1.   <dependency>  
  2.     <groupId>org.hibernate</groupId>  
  3.     <artifactId>hibernate-core</artifactId>  
  4.     <version>5.2.16.Final</version>  
  5. </dependency>  
  6.       
  7. <dependency>  
  8.     <groupId>com.oracle</groupId>  
  9.     <artifactId>ojdbc14</artifactId>  
  10.     <version>10.2.0.4.0</version>  
  11. </dependency>  
  12.       
  13. <dependency>  
  14.     <groupId>net.sf.ehcache</groupId>  
  15.     <artifactId>ehcache</artifactId>  
  16.     <version>2.10.3</version>  
  17. </dependency>  
  18.       
  19.      
  20. <dependency>  
  21.     <groupId>org.hibernate</groupId>  
  22.     <artifactId>hibernate-ehcache</artifactId>  
  23.     <version>5.2.16.Final</version>  
  24. </dependency>  

3) Create the Configuration file

File: hibernate.cfg.xml
  1. <?xml version='1.0' encoding='UTF-8'?>    
  2. <!DOCTYPE hibernate-configuration PUBLIC    
  3.           "-//Hibernate/Hibernate Configuration DTD 5.2.0//EN"    
  4.           "http://hibernate.sourceforge.net/hibernate-configuration-5.2.0.dtd">    
  5.     
  6. <hibernate-configuration>    
  7.     
  8.     <session-factory>    
  9.         <property name="show_sql">true</property>    
  10.         <property name="hbm2ddl.auto">update</property>    
  11.         <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>    
  12.         <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>    
  13.         <property name="connection.username">system</property>    
  14.         <property name="connection.password">jtp</property>    
  15.         <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>    
  16.          
  17.          <property name="cache.use_second_level_cache">true</property>   
  18.          <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>  
  19.          <mapping class="com.tpoint.Employee"/>  
  20.     </session-factory>    
  21. </hibernate-configuration>    

To implement second level cache, we need to define cache.provider_class property in the configuration file.


4) Create the class that retrieves the persistent object.

File: FetchTest.java
  1. package com.tpoint;    
  2.     
  3. import org.hibernate.Session;    
  4. import org.hibernate.SessionFactory;  
  5. import org.hibernate.boot.Metadata;  
  6. import org.hibernate.boot.MetadataSources;  
  7. import org.hibernate.boot.registry.StandardServiceRegistry;  
  8. import org.hibernate.boot.registry.StandardServiceRegistryBuilder;  
  9.     
  10. public class FetchTest {    
  11. public static void main(String[] args) {    
  12.     StandardServiceRegistry ssr=new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();  
  13.     Metadata meta=new MetadataSources(ssr).getMetadataBuilder().build();  
  14.       
  15.     SessionFactory factory=meta.getSessionFactoryBuilder().build();  
  16.         
  17.     Session session1=factory.openSession();    
  18.     Employee emp1=(Employee)session1.load(Employee.class,121);    
  19.     System.out.println(emp1.getId()+" "+emp1.getName()+" "+emp1.getSalary());    
  20.     session1.close();    
  21.         
  22.     Session session2=factory.openSession();    
  23.     Employee emp2=(Employee)session2.load(Employee.class,121);    
  24.     System.out.println(emp2.getId()+" "+emp2.getName()+" "+emp2.getSalary());    
  25.     session2.close();    
  26.         
  27. }    
  28. }