
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Hibernate Second Level Cache Overview
Caching helps to reduce database network call, for executing queries.
First level cache is linked with a session. It is implemented implicitly. First level cache exist only till the session object is there. Once session object is terminated/closed, there will be no cache objects. Second level cache works across multiple sessions objects. It is linked with a session factory. Second level cache objects are available to all the session in a single session factory. These cache objects are terminated when that particular session factory is closed.
Implementing second level caching
We need to add the following dependencies in order to use second level caching.
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.9.2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>5.4.32.Final</version> </dependency>
Note ? hibernate ehcache version number must be same as hibernate version number.
Now, we need to add hibernate configuration file which will enable hibernate to connect to the provided database and use second level caching.
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- JDBC Database connection settings --> <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://localhost:3306/demo?useSSL=false</property> <property name="connection.username">root</property> <property name="connection.password">root</property> <!-- JDBC connection pool settings ... using built-in test pool --> <property name="connection.pool_size">4</property> <!-- Echo the SQL to stdout --> <property name="show_sql">true</property> //caching properties <property name="cache.use_second_level_cache">true</property> <property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!-- Select our SQL dialect --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create-drop</property> <!-- name of annotated entity class --> <mapping class="academy.company.Parent"/> </session-factory> </hibernate-configuration>
Example
By default all the entities in java are non-cached. So to enable caching of an entity, we use @Cacheable and @Cache annotations in our entity class Parent ?
import org.hibernate.annotations.CacheConcurrencyStrategy; import javax.persistence.*; @Entity @Table( name = " Employee") @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_ONLY) public class Parent { @Id @GeneratedValue(strategy = GenerationType.AUTO) Long id; @Column(name = "first_name") String firstName; @Column(name = "last_name") String lastName; } Now, let's check whether second level cache works: import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Main { public static void main(String[] args) { SessionFactory sessionFactory = new Configuration() .configure("academy/company/hibernate.cfg.xml") .buildSessionFactory(); Session session1 = sessionFactory.openSession(); Parent parent1 = session1.get(Parent.class, 4); System.out.println(parent1.id + " " + parent1.firstName + " " + parent1.lastName); session1.close(); Session session2 = sessionFactory.openSession(); Parent parent2 = session2.get(Parent.class, 4); System.out.println(parent2.id + " " + parent2.firstName + " " + parent2.lastName); session2.close(); } }
Output
Hibernate: select parent0.id as id1, parent0.first_name as first_name1, parent0.last_name as last_name1 from Parent parent0 where parent0.id=? 1 Subash Chopra 1 Subash Chopra
We can clearly see from the console that hibernate executed the query only once during session1. Now when the same query is accessed by session2, it will not make a network call to the database for executing it. Instead since we are using second level cache, it will fetch the cache object from session1.