Hi Folks,
Today I'm sharing my learning on hibernate caching mechanism, cache is a wonderful concept for optimizing the application.
There are several vendors who enables the caching in a application. I'm using hibernate-cache.
Caching enables reuse.
It is directly associated with out hibernate life-cycle mostly in persistant state.
If we load any object in a session i.e. we fire a query to DB to get the object. This object is stored in default cache, the advantages of this cache are,
1. if we want to query the same object it will not hit the DB instead it will pick up the data from cache and avoid the DB communication.
2. if we change the value of any object even without using the save or update, and do a transaction, it will update the values.
There are two types of cache
Level-One (by default)
In between same session
Level-Two (Need to enable)
In between multiple session, my below shared example is for level-two cache.
We need to two changes to perform
1. Changes in XML
2. Changes in Bean.
XML Changes
<property name="cache.use_second_level_cache">true</property>
<property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="cache.ehcache.missing_cache_strategy">create</property>
Java Annotations
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.oracle</groupId>
<artifactId>_012RevisionGetLoadFetchCascadeQuery</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.24.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.4.24.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
</dependencies>
</project>
hibernate.cfg.xml
<!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>
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/practice</property>
<property name="connection.user">root</property>
<property name="connection.password">Welcome123#</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="hbm2ddl.auto">update</property>
<property name="cache.use_second_level_cache">true</property>
<property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="cache.ehcache.missing_cache_strategy">create</property>
<mapping class="com.oracle.dto.BankAccount"/>
<mapping class="com.oracle.dto.Citizen"/>
</session-factory>
</hibernate-configuration>
BankAccount.java
package com.oracle.dto;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Date;
@Entity
@Data
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class BankAccount {
@Id
@GeneratedValue(strategy = GenerationType.AUTO,generator = "bid")
@SequenceGenerator(name = "bid",sequenceName = "b_id",initialValue = 2000,allocationSize = 1)
@Setter(AccessLevel.NONE)
@Column(name="bank_id",updatable = false,nullable = false)
private Long bId;
private Integer branchCode;
private Double accountBalance;
@Temporal(TemporalType.DATE)
@Column(name="account_opening_date",updatable = false,nullable = false)
private Date accountOpeningDate;
}
Citizen.java
package com.oracle.dto;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.util.Date;
import java.util.List;
@Entity
@Data
public class Citizen {
@Id
@GeneratedValue(strategy = GenerationType.AUTO, generator = "cid")
@SequenceGenerator(name = "cid", sequenceName = "c_id", initialValue = 1000, allocationSize = 1)
@Setter(AccessLevel.NONE)
@Column(name = "citizen_id", updatable = false, nullable = false)
private Long cId;
@Column(name = "first_name", nullable = false, updatable = true)
private String firstName;
@Column(name = "last_name", nullable = true, updatable = true)
private String lastName;
@Temporal(TemporalType.DATE)
@Column(name = "joining_date", nullable = false, updatable = false)
private Date joiningDate;
@ManyToMany
@JoinTable(name = "citizen_bank",
joinColumns = {@JoinColumn(name = "citizen_id")},
inverseJoinColumns = {@JoinColumn(name = "account_id")})
private List accounts;
}
Main.java
package com.oracle.main;
import com.oracle.dto.BankAccount;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class CacheDriver {
public static void main(String[] args) {
SessionFactory sf=new Configuration().configure().buildSessionFactory();
Session session1 = sf.openSession();
BankAccount account1 = session1.get(BankAccount.class,2000l);
System.out.println(account1);
session1.close();
Session session2 = sf.openSession();
BankAccount account2 = session2.get(BankAccount.class,2000l);
System.out.println(account2);
session1.close();
sf.close();
}
}