In Hibernate, interceptors are used to inspect the changes in entity’s property values before they are written and after they are read from a database.
You can use the Hibernate interceptor to perform the various operations such as logging, auditing, profiling etc.
1. Registering Interceptors
In Hibernate, an interceptor can either be Session-scoped or SessionFactory-scoped.
1. Session-scoped interceptors are used when a Session is opened. The following code snippet shows how to add an interceptor to a Session.
Session session = HibernateUtil.getSessionFactory()
.withOptions()
.interceptor(new MyLogInterceptor())
.openSession();
2. SessionFactory-scoped or global interceptors are used when SessionFactory is configured and these interceptors will be applied to applied to all Session opened from that SessionFactory. The following code snippet shows how to add an interceptor to a SessionFactory.
SessionFactory sessionFactory = metadata.getSessionFactoryBuilder()
.applyInterceptor(new MyLogInterceptor())
.build();
2. How to Create Hibernate Interceptors?
There are two ways of defining interceptors:
1. implementing the org.hibernate.Interceptor interface
2. extending the org.hibernate.EmptyInterceptor class
There are around 14 callback methods which the interceptor provides for us to override and use.
Some of them are onLoad, onDelete, onSave, onFlushDirty, findDirty, etc
If you are creating your interceptor implementing the Interceptor interface then you may need to override all the methods provided.
Instead of implementing this interface directly, it is usually better to extend EmptyInterceptor and override only the callback methods of interest.
3. Example Hibernate Interceptor
1. Create Interceptor Class
By extending EmptyInterceptor Class
import com.pt.entities.Employee;
import org.hibernate.EmptyInterceptor;
import org.hibernate.type.Type;
import java.io.Serializable;
public class MyLogInterceptor extends EmptyInterceptor {
public boolean onSave(Object entity, Serializable id, Object[] state,
String[] propertyNames, Type[] types) {
if (entity instanceof Employee) {
Employee emp = (Employee) entity;
System.out.println(emp.toString());
}
return super.onSave(entity, id, state, propertyNames, types);
}
}
2. Employee Entity looks like this
Create your own set of Entity class like this.
@Entity
@Table(name = "Employee")
@NamedQueries({
@NamedQuery(name = "Employee.findAll", query = "from Employee emp"),
@NamedQuery(name = "Employee.findByName",
query = "from Employee emp where emp.firstName=:firstName"),
})
public class Employee implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "address")
private String address;
// getters & setters & toString()
// ...
}
3. Create HibernateUtility Class – to create session a session factory
Below is the code of HibernateUtility Class – in this we are creating a sessionfactory and registering our Employee Enitity class.
package com.pt.standalone;
import com.pt.entities.Employee;
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;
import org.hibernate.cfg.Environment;
import java.util.HashMap;
import java.util.Map;
public class HibernateUtility {
private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;
public static SessionFactory getSessionFactory() {
if (sessionFactory == null) {
try {
// Create registry builder
StandardServiceRegistryBuilder registryBuilder = new StandardServiceRegistryBuilder();
// Hibernate settings equivalent to hibernate.cfg.xml's properties
Map<String, String> settings = new HashMap<>();
settings.put(Environment.DRIVER, "com.mysql.cj.jdbc.Driver");
settings.put(Environment.URL, "jdbc:mysql://localhost:3306/testdb");
settings.put(Environment.USER, "root");
settings.put(Environment.PASS, "root");
settings.put(Environment.DIALECT, "org.hibernate.dialect.MySQL57Dialect");
// Apply settings
registryBuilder.applySettings(settings);
// Create registry
registry = registryBuilder.build();
// Create MetadataSources
MetadataSources sources = new MetadataSources(registry).addAnnotatedClass(Employee.class);
// Create Metadata
Metadata metadata = sources.getMetadataBuilder().build();
// Create SessionFactory
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Exception e) {
e.printStackTrace();
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
return sessionFactory;
}
public static void shutdown() {
if (registry != null) {
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
4. Run – main method Class
Now run the main class.
import com.pt.entities.Employee;
import org.hibernate.Session;
public class TestHB {
public static void main(String[] args) {
Session session = HibernateUtility.getSessionFactory().withOptions().
interceptor(new MyLogInterceptor()).openSession();
session.beginTransaction();
System.out.println("Save Employee...");
// saving an object
Employee emp = new Employee(10,"mak","robins","NA");
session.save(emp);
}
}
5. Output
Save Employee...
Employee{id=10, firstName='mak', lastName='robins', address='NA'}
Summary
In this article, we learnt about Hibernate Interceptors, how to create hibernate interceptors, its various uses and a working example.
I hope you liked it !