Here we are going to see how to use Hibernate Interceptor while doing hibernate crud operations.
1. Hibernate Interceptor:
Hibernate Interceptors are very useful in applications to react to certain events that occur inside hibernate. Hibernate provides Interceptor interface which gives callback methods from the session to the application.
There are two kinds of interceptors in hibernate:
- Session scoped and
- Session-factory scoped
1.1 Session scoped:
Session scoped interceptor can be specified when a session is opened like below. These session scoped interceptors can bound to a particular session.
Session session = HibernateUtil.getSessionFactory()
.withOptions()
.interceptor(new CrudInterceptor())
.openSession();
1.2 Session-factory scoped:
A session-factory scoped interceptor can be specified with a configuration object prior to the SessionFactory. The provided interceptor will apply to all sessions opened by the session-factory.
StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
Metadata metadata = metadataSources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder()
.applyInterceptor(new CrudInterceptor())
.build();
2. Hibernate Interceptor Example:
In this example, I am going to intercept or manipulate the properties of a persistent object before going to save, update, delete, load or get.
2.1 Versions:
- Hibernate 5.2.12
- MySQL 5.7.25
- MySQL connector
- Java 8
2.2 Project Structure:
2.3 Dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>Hibernate_Interceptor</groupId>
<artifactId>Hibernate_Interceptor_Example</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- MySQL connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<!-- Hibernate 5.2.12 Final -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.12.Final</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.4 Hibernate configuration:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/otp</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.show_sql">true</property>
<mapping class="com.onlinetutorialspoint.entity.Item" />
</session-factory>
</hibernate-configuration>
3. Hibernate Entity:
package com.onlinetutorialspoint.entity;
import javax.persistence.*;
@Entity
@Table(name="item")
public class Item {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name="id")
private int itemId;
@Column(name="item_name",length=30)
private String itemName;
@Column(name="category",length=30)
private String itemCategory;
@Column(name="item_price")
private double itemPrice;
public Item() {
}
public Item(String itemName, String itemCategory, double itemPrice) {
this.itemName = itemName;
this.itemCategory = itemCategory;
this.itemPrice = itemPrice;
}
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemCategory() {
return itemCategory;
}
public void setItemCategory(String itemCategory) {
this.itemCategory = itemCategory;
}
public double getItemPrice() {
return itemPrice;
}
public void setItemPrice(double itemPrice) {
this.itemPrice = itemPrice;
}
@Override
public String toString() {
return "Item{" +
"itemId=" + itemId +
", itemName='" + itemName + '\'' +
", itemCategory='" + itemCategory + '\'' +
", itemPrice=" + itemPrice +
'}';
}
}
4. Hibernate Utility:
package com.onlinetutorialspoint.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
public class HibernateUtil {
private static StandardServiceRegistry standardServiceRegistry;
private static SessionFactory sessionFactory;
static{
if (sessionFactory == null) try {
standardServiceRegistry = new StandardServiceRegistryBuilder()
.configure()
.build();
MetadataSources metadataSources = new MetadataSources(standardServiceRegistry);
Metadata metadata = metadataSources.getMetadataBuilder().build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (standardServiceRegistry != null) {
StandardServiceRegistryBuilder.destroy(standardServiceRegistry);
}
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
5. Hibernate Interceptor:
We can create an interceptor either implementing Interceptor interface or extending the EmptyInterceptor class. However, the EmptyInterceptor class implements Interceptor interface.
Here I am going to extend the EmptyInterface and override some of the methods to intercept my CRUD operations.
package com.onlinetutorialspoint.intereptor;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
public class CrudInterceptor extends EmptyInterceptor {
private static int loadscount;
@Override
public boolean onLoad(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
loadscount++;
System.out.println("Onload Method Called : " + entity + " SerializableId: " + id + " state: " + state);
System.out.println("Load method called " + loadscount + " times");
return super.onLoad(entity, id, state, propertyNames, types);
}
@Override
public boolean onSave(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
System.out.println("Onsave Method Called for : " + entity + " SerializableId: " + id + " state: " + state);
return super.onLoad(entity, id, state, propertyNames, types);
}
@Override
public void onDelete(
Object entity,
Serializable id,
Object[] state,
String[] propertyNames,
Type[] types) {
System.out.println("Ondelete Method Called: " + entity + " SerializableId: " + id + " state: " + state);
}
}
6. Hibernate Main:
Here I created session scoped interceptor while opening Hibernate session.
The intention of the below example is to check whether the interceptor methods being called or not for the appropriate crud operations.
package com.onlinetutorialspoint;
import com.onlinetutorialspoint.util.HibernateUtil;
import com.onlinetutorialspoint.entity.Item;
import com.onlinetutorialspoint.intereptor.CrudInterceptor;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class HibernateInterceptorExample {
public static void main(String[] args) {
Transaction transaction = null;
try (Session session = HibernateUtil.getSessionFactory()
.withOptions()
.interceptor(new CrudInterceptor())
.openSession()) {
transaction = session.beginTransaction();
Item item = new Item();
item.setItemName("iPhobeX");
item.setItemCategory("Mobiles");
item.setItemPrice(120000.00);
// calling save
session.save(item);
transaction.commit();
// calling load method multiple times
Item item1 = (Item) session.load(Item.class, 1701);
Item item2 = session.load(Item.class, 1702);
Item item3 = session.load(Item.class, 1703);
System.out.println("item1: " + item1);
System.out.println("item2: " + item2);
System.out.println("item3: " + item3);
// Calling delete
session.delete(item);
} catch (Exception e) {
e.printStackTrace();
if (transaction != null && transaction.isActive()) {
transaction.rollback();
throw e;
}
}
}
}
Output:
We can observe the interceptor logs while calling session.load(), session.delete() methods.
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
Onsave Method Called for : Item{itemId=1817, itemName='iPhobeX', itemCategory='Mobiles', itemPrice=120000.0} SerializableId: 1817 state: [Ljava.lang.Object;@a4b2d8f
Hibernate: insert into item (category, item_name, item_price, id) values (?, ?, ?, ?)
Hibernate: select item0_.id as id1_0_0_, item0_.category as category2_0_0_, item0_.item_name as item_nam3_0_0_, item0_.item_price as item_pri4_0_0_ from item item0_ where item0_.id=?
Onload Method Called : Item{itemId=1701, itemName='null', itemCategory='null', itemPrice=0.0} SerializableId: 1701 state: [Ljava.lang.Object;@29e6eb25
Load method called 1 times
item: Item{itemId=1701, itemName='Samsung', itemCategory='Mobiles', itemPrice=15000.0}
Hibernate: select item0_.id as id1_0_0_, item0_.category as category2_0_0_, item0_.item_name as item_nam3_0_0_, item0_.item_price as item_pri4_0_0_ from item item0_ where item0_.id=?
Onload Method Called : Item{itemId=1702, itemName='null', itemCategory='null', itemPrice=0.0} SerializableId: 1702 state: [Ljava.lang.Object;@269f4bad
Load method called 2 times
item: Item{itemId=1702, itemName='Lenovo', itemCategory='Mobiles', itemPrice=12000.0}
Hibernate: select item0_.id as id1_0_0_, item0_.category as category2_0_0_, item0_.item_name as item_nam3_0_0_, item0_.item_price as item_pri4_0_0_ from item item0_ where item0_.id=?
Onload Method Called : Item{itemId=1703, itemName='null', itemCategory='null', itemPrice=0.0} SerializableId: 1703 state: [Ljava.lang.Object;@275fe372
Load method called 3 times
item: Item{itemId=1703, itemName='Hibernate in Action', itemCategory='Books', itemPrice=7500.0}
Ondelete Method Called: Item{itemId=1817, itemName='iPhobeX', itemCategory='Mobiles', itemPrice=120000.0} SerializableId: 1817 state: [Ljava.lang.Object;@31e75d13
Resources:
Hibernate session.load() vs session.get()
Happy Learning 🙂