org.hibernate.Interceptor Maven / Gradle / Ivy
Show all versions of beangle-hibernate-core Show documentation
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate;
import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.metamodel.RepresentationMode;
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
import org.hibernate.type.Type;
/**
* Allows user code to inspect and/or change entity property values before they are
* written to the database, or after they are read from the database.
*
* - For a {@linkplain Session stateful session}, the callbacks {@link #onLoad},
* {@link #onPersist}, {@link #onRemove}, and {@link #onFlushDirty} reflect the
* basic lifecycle of a managed entity.
*
- For a {@linkplain StatelessSession stateless session}, the relevant callbacks
* are {@link #onLoad}, {@link #onInsert}, {@link #onUpdate}, {@link #onUpsert}, and
* {@link #onDelete(Object entity, Object id, String[] propertyNames, Type[] propertyTypes)
* onDelete}.
*
*
* The {@link Session} may not be invoked from a callback (nor may a callback cause
* a collection or proxy to be lazily initialized).
*
* There might be a single instance of {@code Interceptor} for a {@link SessionFactory},
* or a new instance might be created for each {@link Session}. Use:
*
* - {@link org.hibernate.cfg.AvailableSettings#INTERCEPTOR} to specify an
* interceptor shared between sessions, or
*
- {@link org.hibernate.cfg.AvailableSettings#SESSION_SCOPED_INTERCEPTOR} to
* specify that there is a dedicated instance of the interceptor for each
* session.
*
*
* Whichever approach is used, the interceptor must be serializable for the
* {@code Session} to be serializable. This means that {@code SessionFactory}-scoped
* interceptors should implement {@code readResolve()}.
*
* This venerable callback interface, dating to the very earliest days of Hibernate,
* competes with JPA entity listener callbacks: {@link jakarta.persistence.PostLoad},
* {@link jakarta.persistence.PrePersist} {@link jakarta.persistence.PreUpdate}, and
* {@link jakarta.persistence.PreRemove}.
*
* @see SessionBuilder#interceptor(Interceptor)
* @see SharedSessionBuilder#interceptor()
* @see org.hibernate.cfg.Configuration#setInterceptor(Interceptor)
*
* @see org.hibernate.boot.SessionFactoryBuilder#applyInterceptor(Interceptor)
* @see org.hibernate.boot.SessionFactoryBuilder#applyStatelessInterceptor(Class)
*
* @author Gavin King
*/
public interface Interceptor {
/**
* Called just before an object is initialized. The interceptor may change the {@code state}, which will
* be propagated to the persistent object. Note that when this method is called, {@code entity} will be
* an empty uninitialized instance of the class.
*
* @apiNote The indexes across the {@code state}, {@code propertyNames}, and {@code types} arrays match.
*
* @param entity The entity instance being loaded
* @param id The identifier value being loaded
* @param state The entity state (which will be pushed into the entity instance)
* @param propertyNames The names of the entity properties, corresponding to the {@code state}.
* @param types The types of the entity properties, corresponding to the {@code state}.
*
* @return {@code true} if the user modified the {@code state} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default boolean onLoad(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (id==null || id instanceof Serializable) {
return onLoad(entity, (Serializable) id, state, propertyNames, types);
}
return false;
}
/**
* Called just before an object is initialized. The interceptor may change the {@code state}, which will
* be propagated to the persistent object. Note that when this method is called, {@code entity} will be
* an empty uninitialized instance of the class.
*
* @apiNote The indexes across the {@code state}, {@code propertyNames}, and {@code types} arrays match.
*
* @param entity The entity instance being loaded
* @param id The identifier value being loaded
* @param state The entity state (which will be pushed into the entity instance)
* @param propertyNames The names of the entity properties, corresponding to the {@code state}.
* @param types The types of the entity properties, corresponding to the {@code state}.
*
* @return {@code true} if the user modified the {@code state} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onLoad(Object, Object, Object[], String[], Type[])}
*/
@Deprecated(since = "6.0")
default boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
return false;
}
/**
* Called before an object is made persistent by a stateful session.
*
* The interceptor may modify the {@code state}, which will be used for
* the SQL {@code INSERT} and propagated to the persistent object.
*
* @param entity The entity instance whose state is being inserted
* @param id The identifier of the entity
* @param state The state of the entity which will be inserted
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @return {@code true} if the user modified the {@code state} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @see Session#persist(Object)
* @see Session#merge(Object)
*/
default boolean onPersist(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
return onSave(entity, id, state, propertyNames, types);
}
/**
* Called before an object is removed by a stateful session.
*
* It is not recommended that the interceptor modify the {@code state}.
*
* @param entity The entity instance being deleted
* @param id The identifier of the entity
* @param state The state of the entity
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @see Session#remove(Object)
*/
default void onRemove(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
onDelete(entity, id, state, propertyNames, types);
}
/**
* Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected
* {@code currentState}, which will be propagated to both the database and the persistent object.
* Note that not all flushes end in actual synchronization with the database, in which case the
* new {@code currentState} will be propagated to the object, but not necessarily (immediately) to
* the database. It is strongly recommended that the interceptor not modify the {@code previousState}.
*
* @apiNote The indexes across the {@code currentState}, {@code previousState}, {@code propertyNames}, and
* {@code types} arrays match.
*
* @param entity The entity instance detected as being dirty and being flushed
* @param id The identifier of the entity
* @param currentState The entity's current state
* @param previousState The entity's previous (load time) state.
* @param propertyNames The names of the entity properties
* @param types The types of the entity properties
*
* @return {@code true} if the user modified the {@code currentState} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @see Session#flush()
*/
default boolean onFlushDirty(
Object entity,
Object id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) throws CallbackException {
if (id==null || id instanceof Serializable) {
return onFlushDirty(entity, (Serializable) id, currentState, previousState, propertyNames, types);
}
return false;
}
/**
* Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected
* {@code currentState}, which will be propagated to both the database and the persistent object.
* Note that not all flushes end in actual synchronization with the database, in which case the
* new {@code currentState} will be propagated to the object, but not necessarily (immediately) to
* the database. It is strongly recommended that the interceptor not modify the {@code previousState}.
*
* @apiNote The indexes across the {@code currentState}, {@code previousState}, {@code propertyNames}, and
* {@code types} arrays match.
*
* @param entity The entity instance detected as being dirty and being flushed
* @param id The identifier of the entity
* @param currentState The entity's current state
* @param previousState The entity's previous (load time) state.
* @param propertyNames The names of the entity properties
* @param types The types of the entity properties
*
* @return {@code true} if the user modified the {@code currentState} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onFlushDirty(Object, Object, Object[], Object[], String[], Type[])}
*/
@Deprecated(since = "6.0")
default boolean onFlushDirty(
Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types) throws CallbackException {
return false;
}
/**
* Called before an object is made persistent by a stateful session.
*
* The interceptor may modify the {@code state}, which will be used for
* the SQL {@code INSERT} and propagated to the persistent object.
*
* @param entity The entity instance whose state is being inserted
* @param id The identifier of the entity
* @param state The state of the entity which will be inserted
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @return {@code true} if the user modified the {@code state} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onSave(Object, Object, Object[], String[], Type[])}
*/
@Deprecated(since = "6.0")
default boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
return false;
}
/**
* Called before an object is made persistent by a stateful session.
*
* The interceptor may modify the {@code state}, which will be used for
* the SQL {@code INSERT} and propagated to the persistent object.
*
* @param entity The entity instance whose state is being inserted
* @param id The identifier of the entity
* @param state The state of the entity which will be inserted
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @return {@code true} if the user modified the {@code state} in any way.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @see Session#persist(Object)
* @see Session#merge(Object)
* @see Session#save(Object)
*
* @deprecated Use {@link #onPersist(Object, Object, Object[], String[], Type[])}
*/
@Deprecated(since = "6.6")
default boolean onSave(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (id==null || id instanceof Serializable) {
return onSave(entity, (Serializable) id, state, propertyNames, types);
}
return false;
}
/**
* Called before an object is removed by a stateful session.
*
* It is not recommended that the interceptor modify the {@code state}.
*
* @param entity The entity instance being deleted
* @param id The identifier of the entity
* @param state The state of the entity
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onDelete(Object, Object, Object[], String[], Type[])}
*/
@Deprecated(since = "6.0")
default void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {}
/**
* Called before an object is removed by a stateful session.
*
* It is not recommended that the interceptor modify the {@code state}.
*
* @param entity The entity instance being deleted
* @param id The identifier of the entity
* @param state The state of the entity
* @param propertyNames The names of the entity properties.
* @param types The types of the entity properties
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @see Session#remove(Object)
* @see Session#delete(Object)
*
* @deprecated Use {@link #onRemove(Object, Object, Object[], String[], Type[])}
*/
@Deprecated(since = "6.6")
default void onDelete(Object entity, Object id, Object[] state, String[] propertyNames, Type[] types)
throws CallbackException {
if (id==null || id instanceof Serializable) {
onDelete(entity, (Serializable) id, state, propertyNames, types);
}
}
/**
* Called before a collection is (re)created.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onCollectionRecreate(Object, Object)}
*/
@Deprecated(since = "6.0")
default void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {}
/**
* Called before a collection is (re)created.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default void onCollectionRecreate(Object collection, Object key) throws CallbackException {
if (key instanceof Serializable) {
onCollectionRecreate(collection, (Serializable) key);
}
}
/**
* Called before a collection is deleted.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onCollectionRemove(Object, Object)}
*/
@Deprecated(since = "6.0")
default void onCollectionRemove(Object collection, Serializable key) throws CallbackException {}
/**
* Called before a collection is deleted.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default void onCollectionRemove(Object collection, Object key) throws CallbackException {
if (key instanceof Serializable) {
onCollectionRemove(collection, (Serializable) key);
}
}
/**
* Called before a collection is updated.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*
* @deprecated use {@link #onCollectionUpdate(Object, Object)}
*/
@Deprecated(since = "6.0")
default void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {}
/**
* Called before a collection is updated.
*
* @param collection The collection instance.
* @param key The collection key value.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default void onCollectionUpdate(Object collection, Object key) throws CallbackException {
if (key instanceof Serializable) {
onCollectionUpdate(collection, (Serializable) key);
}
}
/**
* Called before a flush.
*
* @param entities The entities to be flushed.
*
* @throws CallbackException Thrown if the interceptor encounters any problems handling the callback.
*/
default void preFlush(Iterator