Hibernate Tutorial
Core Hibernate
Hibernate Mapping
Hibernate Annotations
Hibernate with Spring Framework
Hibernate with Database
Hibernate Log4j
Inheritance Mapping
Interceptors in Hibernate allow developers to track and manage specific events related to the persistence lifecycle. They are powerful tools that provide hooks for session operations. For example, you can use interceptors to log, audit, or even modify an entity before it is saved, updated, or deleted.
In this tutorial, we'll provide a brief introduction to Hibernate interceptors.
To create an interceptor, you have to implement the org.hibernate.Interceptor
interface. Here's a simple example of an interceptor that logs changes:
import org.hibernate.EmptyInterceptor; import org.hibernate.type.Type; public class LoggingInterceptor extends EmptyInterceptor { @Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { System.out.println("Before saving " + entity); return super.onSave(entity, id, state, propertyNames, types); } }
In the example above, we are using the onSave
method which is invoked just before an object is saved. You can override other methods like onDelete
, onFlushDirty
, etc., to handle different lifecycle events.
There are two primary ways to configure an interceptor:
During SessionFactory Creation:
If you're creating the SessionFactory programmatically, you can set the interceptor like this:
Configuration configuration = new Configuration(); configuration.setInterceptor(new LoggingInterceptor()); SessionFactory sessionFactory = configuration.buildSessionFactory();
During Session Creation:
You can also associate an interceptor with a specific session:
Session session = sessionFactory.withOptions().interceptor(new LoggingInterceptor()).openSession();
Beyond just logging, you can modify the entity. For example, you could set audit fields:
@Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { if (entity instanceof Auditable) { Date now = new Date(); ((Auditable) entity).setCreatedDate(now); ((Auditable) entity).setModifiedDate(now); } return super.onSave(entity, id, state, propertyNames, types); } @Override public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) { if (entity instanceof Auditable) { ((Auditable) entity).setModifiedDate(new Date()); } return super.onFlushDirty(entity, id, currentState, previousState, propertyNames, types); }
In the above code, the Auditable
interface might be an interface you define that has methods like setCreatedDate
and setModifiedDate
to manage audit data.
To conclude, interceptors offer a powerful mechanism to introduce custom behavior at various stages of the Hibernate persistence lifecycle. Whether for logging, auditing, or other cross-cutting concerns, they provide a useful means of enhancing or extending the default Hibernate behavior.
Implementing custom interceptors in Hibernate:
EmptyInterceptor
or implementing the Interceptor
interface. Override methods like onLoad
, onSave
, and onDelete
to add custom behavior.public class CustomInterceptor extends EmptyInterceptor { @Override public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { // Custom logic before saving return super.onSave(entity, id, state, propertyNames, types); } }
Hibernate session-level interceptors:
Session.setInterceptor()
. This allows you to have different interceptors for different sessions in the same application.Session session = sessionFactory.openSession(); CustomInterceptor customInterceptor = new CustomInterceptor(); session.setInterceptor(customInterceptor);