Merge remote-tracking branch 'upstream/main' into wip/6.0_merge

This commit is contained in:
Andrea Boriero 2021-10-15 12:07:14 +02:00
commit c545cee28c
15 changed files with 283 additions and 187 deletions

View File

@ -101,6 +101,8 @@ import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.loader.PropertyPath;
import org.hibernate.mapping.Any;
import org.hibernate.mapping.BasicValue;
@ -837,6 +839,8 @@ public final class AnnotationBinder {
entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Table.class ) );
entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Tables.class ) );
entityBinder.processComplementaryTableDefinitions( tabAnn );
bindCallbacks( clazzToProcess, persistentClass, context );
}
private static void handleTypeDescriptorRegistrations(XAnnotatedElement annotatedElement, MetadataBuildingContext context) {
@ -1432,6 +1436,32 @@ public final class AnnotationBinder {
context.getMetadataCollector().addFilterDefinition( def );
}
private static void bindCallbacks(XClass entityClass, PersistentClass persistentClass,
MetadataBuildingContext context) {
ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager();
for ( CallbackType callbackType : CallbackType.values() ) {
persistentClass.addCallbackDefinitions( CallbackDefinitionResolverLegacyImpl.resolveEntityCallbacks(
reflectionManager, entityClass, callbackType ) );
}
context.getMetadataCollector().addSecondPass( new SecondPass() {
@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
for ( @SuppressWarnings("unchecked") Iterator<Property> propertyIterator = persistentClass.getDeclaredPropertyIterator();
propertyIterator.hasNext(); ) {
Property property = propertyIterator.next();
if ( property.isComposite() ) {
for ( CallbackType callbackType : CallbackType.values() ) {
property.addCallbackDefinitions( CallbackDefinitionResolverLegacyImpl.resolveEmbeddableCallbacks(
reflectionManager, persistentClass.getMappedClass(), property, callbackType ) );
}
}
}
}
} );
}
public static void bindFetchProfilesForClass(XClass clazzToProcess, MetadataBuildingContext context) {
bindFetchProfiles( clazzToProcess, context );
}
@ -1476,7 +1506,6 @@ public final class AnnotationBinder {
}
}
private static void bindDiscriminatorColumnToRootPersistentClass(
RootClass rootClass,
Ejb3DiscriminatorColumn discriminatorColumn,

View File

@ -9,7 +9,6 @@ package org.hibernate.event.spi;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Consumer;
@ -23,9 +22,6 @@ import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.jpa.event.internal.CallbackRegistryImplementor;
import org.hibernate.jpa.event.internal.CallbacksFactory;
import org.hibernate.jpa.event.spi.CallbackBuilder;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.service.spi.Stoppable;
/**
@ -39,7 +35,6 @@ public class EventEngine {
private final EventListenerRegistry listenerRegistry;
private final CallbackRegistryImplementor callbackRegistry;
private final CallbackBuilder callbackBuilder;
public EventEngine(
MetadataImplementor mappings,
@ -48,33 +43,8 @@ public class EventEngine {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// resolve (JPA) callback handlers
this.callbackRegistry = CallbacksFactory.buildCallbackRegistry( sessionFactory.getSessionFactoryOptions() );
this.callbackBuilder = CallbacksFactory.buildCallbackBuilder(
sessionFactory.getSessionFactoryOptions(),
sessionFactory.getServiceRegistry(),
mappings.getMetadataBuildingOptions().getReflectionManager()
);
for ( PersistentClass persistentClass : mappings.getEntityBindings() ) {
if ( persistentClass.getClassName() == null ) {
// we can have dynamic (non-java class) mapping
continue;
}
this.callbackBuilder.buildCallbacksForEntity( persistentClass.getMappedClass(), callbackRegistry );
for ( Iterator<Property> propertyIterator = persistentClass.getDeclaredPropertyIterator(); propertyIterator.hasNext(); ) {
final Property property = propertyIterator.next();
if ( property.isComposite() ) {
this.callbackBuilder.buildCallbacksForEmbeddable(
property,
persistentClass.getMappedClass(),
callbackRegistry
);
}
}
}
this.callbackRegistry = CallbacksFactory.buildCallbackRegistry( sessionFactory.getSessionFactoryOptions(),
sessionFactory.getServiceRegistry(), mappings.getEntityBindings() );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -192,7 +162,5 @@ public class EventEngine {
}
callbackRegistry.release();
callbackBuilder.release();
}
}

View File

@ -19,88 +19,39 @@ import jakarta.persistence.ExcludeSuperclassListeners;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PersistenceException;
import org.hibernate.MappingException;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XMethod;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.jpa.event.spi.Callback;
import org.hibernate.jpa.event.spi.CallbackBuilder;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.jboss.logging.Logger;
/**
* EntityCallbackBuilder implementation using HCANN ReflectionManager. "legacy" in that
* we want to move to Jandex instead.
* Resolves JPA callback definitions using a HCANN ReflectionManager.
* <p>
* "legacy" in that we want to move to Jandex instead.
*
* @author Steve Ebersole
*/
final class CallbackBuilderLegacyImpl implements CallbackBuilder {
private static final Logger log = Logger.getLogger( CallbackBuilderLegacyImpl.class );
private final ManagedBeanRegistry managedBeanRegistry;
private final ReflectionManager reflectionManager;
CallbackBuilderLegacyImpl(ManagedBeanRegistry managedBeanRegistry, ReflectionManager reflectionManager) {
this.managedBeanRegistry = managedBeanRegistry;
this.reflectionManager = reflectionManager;
}
@Override
public void buildCallbacksForEntity(Class entityClass, CallbackRegistrar callbackRegistrar) {
for ( CallbackType callbackType : CallbackType.values() ) {
if ( callbackRegistrar.hasRegisteredCallbacks( entityClass, callbackType ) ) {
// this most likely means we have a class mapped multiple times using the hbm.xml
// "entity name" feature
if ( log.isDebugEnabled() ) {
log.debugf(
"CallbackRegistry reported that Class [%s] already had %s callbacks registered; " +
"assuming this means the class was mapped twice " +
"(using hbm.xml entity-name support) - skipping subsequent registrations",
entityClass.getName(),
callbackType.getCallbackAnnotation().getSimpleName()
);
}
continue;
}
final Callback[] callbacks = resolveEntityCallbacks( entityClass, callbackType, reflectionManager );
callbackRegistrar.registerCallbacks( entityClass, callbacks );
}
}
@Override
public void buildCallbacksForEmbeddable(
Property embeddableProperty, Class entityClass, CallbackRegistrar callbackRegistrar) {
for ( CallbackType callbackType : CallbackType.values() ) {
final Callback[] callbacks = resolveEmbeddableCallbacks(
entityClass,
embeddableProperty,
callbackType,
reflectionManager
);
callbackRegistrar.registerCallbacks( entityClass, callbacks );
}
}
@Override
public void release() {
// nothing to do
}
public final class CallbackDefinitionResolverLegacyImpl {
private static final Logger log = Logger.getLogger( CallbackDefinitionResolverLegacyImpl.class );
@SuppressWarnings({"unchecked", "WeakerAccess"})
public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbackType, ReflectionManager reflectionManager) {
List<Callback> callbacks = new ArrayList<>();
public static List<CallbackDefinition> resolveEntityCallbacks(ReflectionManager reflectionManager,
XClass entityClass, CallbackType callbackType) {
List<CallbackDefinition> callbackDefinitions = new ArrayList<>();
List<String> callbacksMethodNames = new ArrayList<>();
List<Class> orderedListeners = new ArrayList<>();
XClass currentClazz = reflectionManager.toXClass( entityClass );
XClass currentClazz = entityClass;
boolean stopListeners = false;
boolean stopDefaultListeners = false;
do {
Callback callback = null;
CallbackDefinition callbackDefinition = null;
List<XMethod> methods = currentClazz.getDeclaredMethods();
for ( final XMethod xMethod : methods ) {
if ( xMethod.isAnnotationPresent( callbackType.getCallbackAnnotation() ) ) {
@ -108,8 +59,8 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
final String methodName = method.getName();
if ( !callbacksMethodNames.contains( methodName ) ) {
//overridden method, remove the superclass overridden method
if ( callback == null ) {
callback = new EntityCallback( method, callbackType );
if ( callbackDefinition == null ) {
callbackDefinition = new EntityCallback.Definition( method, callbackType );
Class returnType = method.getReturnType();
Class[] args = method.getParameterTypes();
if ( returnType != Void.TYPE || args.length != 0 ) {
@ -127,7 +78,7 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
entityClass.getName()
);
}
callbacks.add( 0, callback ); //superclass first
callbackDefinitions.add( 0, callbackDefinition ); //superclass first
callbacksMethodNames.add( 0, methodName );
}
else {
@ -168,7 +119,7 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
}
for ( Class listener : orderedListeners ) {
Callback callback = null;
CallbackDefinition callbackDefinition = null;
if ( listener != null ) {
XClass xListener = reflectionManager.toXClass( listener );
callbacksMethodNames = new ArrayList<>();
@ -179,12 +130,8 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
final String methodName = method.getName();
if ( !callbacksMethodNames.contains( methodName ) ) {
//overridden method, remove the superclass overridden method
if ( callback == null ) {
callback = new ListenerCallback(
managedBeanRegistry.getBean( listener ),
method,
callbackType
);
if ( callbackDefinition == null ) {
callbackDefinition = new ListenerCallback.Definition( listener, method, callbackType );
Class returnType = method.getReturnType();
Class[] args = method.getParameterTypes();
@ -203,7 +150,7 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
entityClass.getName()
);
}
callbacks.add( 0, callback ); // listeners first
callbackDefinitions.add( 0, callbackDefinition ); // listeners first
}
else {
throw new PersistenceException(
@ -218,20 +165,20 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
}
}
}
return callbacks.toArray( new Callback[callbacks.size()] );
return callbackDefinitions;
}
@SuppressWarnings({"unchecked", "WeakerAccess"})
public Callback[] resolveEmbeddableCallbacks(Class entityClass, Property embeddableProperty, CallbackType callbackType, ReflectionManager reflectionManager) {
public static List<CallbackDefinition> resolveEmbeddableCallbacks(ReflectionManager reflectionManager,
Class<?> entityClass, Property embeddableProperty,
CallbackType callbackType) {
final Class embeddableClass = embeddableProperty.getType().getReturnedClass();
final XClass embeddableXClass = reflectionManager.toXClass( embeddableClass );
final Getter embeddableGetter = embeddableProperty.getGetter( entityClass );
final List<Callback> callbacks = new ArrayList<>();
final List<CallbackDefinition> callbackDefinitions = new ArrayList<>();
final List<String> callbacksMethodNames = new ArrayList<>();
XClass currentClazz = embeddableXClass;
do {
Callback callback = null;
CallbackDefinition callbackDefinition = null;
List<XMethod> methods = currentClazz.getDeclaredMethods();
for ( final XMethod xMethod : methods ) {
if ( xMethod.isAnnotationPresent( callbackType.getCallbackAnnotation() ) ) {
@ -239,8 +186,8 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
final String methodName = method.getName();
if ( !callbacksMethodNames.contains( methodName ) ) {
//overridden method, remove the superclass overridden method
if ( callback == null ) {
callback = new EmbeddableCallback( embeddableGetter, method, callbackType );
if ( callbackDefinition == null ) {
callbackDefinition = new EmbeddableCallback.Definition( embeddableGetter, method, callbackType );
Class returnType = method.getReturnType();
Class[] args = method.getParameterTypes();
if ( returnType != Void.TYPE || args.length != 0 ) {
@ -258,7 +205,7 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
embeddableXClass.getName()
);
}
callbacks.add( 0, callback ); //superclass first
callbackDefinitions.add( 0, callbackDefinition ); //superclass first
callbacksMethodNames.add( 0, methodName );
}
else {
@ -278,7 +225,7 @@ final class CallbackBuilderLegacyImpl implements CallbackBuilder {
}
while ( currentClazz != null );
return callbacks.toArray( new Callback[callbacks.size()] );
return callbackDefinitions;
}
private static boolean useAnnotationAnnotatedByListener;

View File

@ -41,13 +41,15 @@ final class CallbackRegistryImpl implements CallbackRegistryImplementor {
return;
}
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( callbacks[0].getCallbackType() );
Callback[] entityCallbacks = map.get( entityClass );
if ( entityCallbacks != null ) {
callbacks = ArrayHelper.join( entityCallbacks, callbacks );
for ( Callback callback : callbacks ) {
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( callback.getCallbackType() );
Callback[] entityCallbacks = map.get( entityClass );
if ( entityCallbacks == null ) {
entityCallbacks = new Callback[0];
}
entityCallbacks = ArrayHelper.join( entityCallbacks, callback );
map.put( entityClass, entityCallbacks );
}
map.put( entityClass, callbacks );
}
@Override

View File

@ -7,9 +7,9 @@
package org.hibernate.jpa.event.internal;
import org.hibernate.jpa.event.spi.CallbackBuilder;
import org.hibernate.jpa.event.spi.CallbackRegistry;
import org.hibernate.jpa.event.spi.CallbackRegistrar;
public interface CallbackRegistryImplementor extends CallbackRegistry, CallbackBuilder.CallbackRegistrar {
public interface CallbackRegistryImplementor extends CallbackRegistrar, CallbackBuilder.CallbackRegistrar {
void release();

View File

@ -6,42 +6,89 @@
*/
package org.hibernate.jpa.event.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.hibernate.annotations.common.reflection.ReflectionManager;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.jpa.event.spi.CallbackBuilder;
import org.hibernate.jpa.event.spi.Callback;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.ServiceRegistry;
import org.jboss.logging.Logger;
/**
* The intent of this class is to use a lighter implementation
* when JPA callbacks are disabled via
* {@link SessionFactoryOptions#areJPACallbacksEnabled()}
*/
public final class CallbacksFactory {
public static CallbackRegistryImplementor buildCallbackRegistry(SessionFactoryOptions options) {
if ( jpaCallBacksEnabled( options ) ) {
return new CallbackRegistryImpl();
}
else {
private static final Logger log = Logger.getLogger( CallbacksFactory.class );
public static CallbackRegistryImplementor buildCallbackRegistry(SessionFactoryOptions options,
ServiceRegistry serviceRegistry, Collection<PersistentClass> entityBindings) {
if ( !jpaCallBacksEnabled( options ) ) {
return new EmptyCallbackRegistryImpl();
}
ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
CallbackRegistryImplementor registry = new CallbackRegistryImpl();
Set<Class<?>> entityClasses = new HashSet<>();
for ( PersistentClass persistentClass : entityBindings ) {
if ( persistentClass.getClassName() == null ) {
// we can have dynamic (non-java class) mapping
continue;
}
Class<?> entityClass = persistentClass.getMappedClass();
if ( !entityClasses.add( entityClass ) ) {
// this most likely means we have a class mapped multiple times using the hbm.xml
// "entity name" feature
if ( log.isDebugEnabled() ) {
log.debugf(
"Class [%s] already has callbacks registered; " +
"assuming this means the class was mapped twice " +
"(using hbm.xml entity-name support) - skipping subsequent registrations" +
"to avoid duplicates",
entityClass.getName()
);
}
continue;
}
registry.registerCallbacks( persistentClass.getMappedClass(),
buildCallbacks( persistentClass.getCallbackDefinitions(), beanRegistry ) );
for ( @SuppressWarnings("unchecked") Iterator<Property> propertyIterator = persistentClass.getDeclaredPropertyIterator();
propertyIterator.hasNext(); ) {
final Property property = propertyIterator.next();
registry.registerCallbacks( persistentClass.getMappedClass(),
buildCallbacks( property.getCallbackDefinitions(), beanRegistry ) );
}
}
return registry;
}
public static CallbackBuilder buildCallbackBuilder(
SessionFactoryOptions options,
ServiceRegistry serviceRegistry,
ReflectionManager reflectionManager) {
if ( jpaCallBacksEnabled( options ) ) {
final ManagedBeanRegistry managedBeanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
return new CallbackBuilderLegacyImpl(
managedBeanRegistry,
reflectionManager
);
private static Callback[] buildCallbacks(List<CallbackDefinition> callbackDefinitions,
ManagedBeanRegistry beanRegistry) {
if ( callbackDefinitions == null || callbackDefinitions.isEmpty() ) {
return null;
}
else {
return new EmptyCallbackBuilder();
List<Callback> callbacks = new ArrayList<>();
for ( CallbackDefinition definition : callbackDefinitions ) {
callbacks.add( definition.createCallback( beanRegistry ) );
}
return callbacks.toArray( new Callback[0] );
}
private static boolean jpaCallBacksEnabled(SessionFactoryOptions options) {

View File

@ -9,8 +9,11 @@ package org.hibernate.jpa.event.internal;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.hibernate.jpa.event.spi.Callback;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
/**
* Represents a JPA callback on the embeddable type
@ -19,10 +22,27 @@ import org.hibernate.property.access.spi.Getter;
*/
final class EmbeddableCallback extends AbstractCallback {
public static class Definition implements CallbackDefinition {
private final Getter embeddableGetter;
private final Method callbackMethod;
private final CallbackType callbackType;
public Definition(Getter embeddableGetter, Method callbackMethod, CallbackType callbackType) {
this.embeddableGetter = embeddableGetter;
this.callbackMethod = callbackMethod;
this.callbackType = callbackType;
}
@Override
public Callback createCallback(ManagedBeanRegistry beanRegistry) {
return new EmbeddableCallback( embeddableGetter, callbackMethod, callbackType );
}
}
private final Getter embeddableGetter;
private final Method callbackMethod;
EmbeddableCallback(Getter embeddableGetter, Method callbackMethod, CallbackType callbackType) {
private EmbeddableCallback(Getter embeddableGetter, Method callbackMethod, CallbackType callbackType) {
super( callbackType );
this.embeddableGetter = embeddableGetter;
this.callbackMethod = callbackMethod;

View File

@ -1,29 +0,0 @@
/*
* 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 http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.jpa.event.internal;
import org.hibernate.jpa.event.spi.CallbackBuilder;
import org.hibernate.mapping.Property;
final class EmptyCallbackBuilder implements CallbackBuilder {
@Override
public void buildCallbacksForEntity(Class entityClass, CallbackRegistrar callbackRegistrar) {
//no-op
}
@Override
public void buildCallbacksForEmbeddable(Property embeddableProperty, Class entityClass, CallbackRegistrar callbackRegistrar) {
//no-op
}
@Override
public void release() {
//no-op
}
}

View File

@ -9,7 +9,10 @@ package org.hibernate.jpa.event.internal;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.hibernate.jpa.event.spi.Callback;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
/**
* Represents a JPA callback on the entity itself
@ -19,9 +22,24 @@ import org.hibernate.jpa.event.spi.CallbackType;
*/
final class EntityCallback extends AbstractCallback {
public static class Definition implements CallbackDefinition {
private final Method callbackMethod;
private final CallbackType callbackType;
public Definition(Method callbackMethod, CallbackType callbackType) {
this.callbackMethod = callbackMethod;
this.callbackType = callbackType;
}
@Override
public Callback createCallback(ManagedBeanRegistry beanRegistry) {
return new EntityCallback( callbackMethod, callbackType );
}
}
private final Method callbackMethod;
EntityCallback(Method callbackMethod, CallbackType callbackType) {
private EntityCallback(Method callbackMethod, CallbackType callbackType) {
super( callbackType );
this.callbackMethod = callbackMethod;
}

View File

@ -9,8 +9,11 @@ package org.hibernate.jpa.event.internal;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.hibernate.jpa.event.spi.Callback;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.jpa.event.spi.CallbackType;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
/**
* Represents a JPA callback using a dedicated listener
@ -20,10 +23,27 @@ import org.hibernate.resource.beans.spi.ManagedBean;
*/
class ListenerCallback extends AbstractCallback {
private final Method callbackMethod;
private final ManagedBean listenerManagedBean;
public static class Definition implements CallbackDefinition {
private final Class<?> listenerClass;
private final Method callbackMethod;
private final CallbackType callbackType;
ListenerCallback(ManagedBean listenerManagedBean, Method callbackMethod, CallbackType callbackType) {
public Definition(Class<?> listenerClass, Method callbackMethod, CallbackType callbackType) {
this.listenerClass = listenerClass;
this.callbackMethod = callbackMethod;
this.callbackType = callbackType;
}
@Override
public Callback createCallback(ManagedBeanRegistry beanRegistry) {
return new ListenerCallback( beanRegistry.getBean( listenerClass ), callbackMethod, callbackType );
}
}
private final Method callbackMethod;
private final ManagedBean<?> listenerManagedBean;
ListenerCallback(ManagedBean<?> listenerManagedBean, Method callbackMethod, CallbackType callbackType) {
super( callbackType );
this.listenerManagedBean = listenerManagedBean;
this.callbackMethod = callbackMethod;

View File

@ -12,20 +12,18 @@ import org.hibernate.mapping.Property;
* Contract for walking an entity hierarchy and building a list of JPA callbacks
*
* @author Steve Ebersole
*
* @deprecated This SPI has never been functional and is no longer used. It will eventually be removed.
*/
@Deprecated
public interface CallbackBuilder {
/**
* Represents the target of JPA callback registrations as part the EntityCallbackBuilder
*
* @deprecated Use {@link org.hibernate.jpa.event.spi.CallbackRegistrar} instead.
*/
interface CallbackRegistrar extends CallbackRegistry {
/**
* Register the callback against the given entity.
*
* @param entityClass The entity Class to register the Callbacks against
* @param callbacks The Callbacks to register against the given entity Class
*/
void registerCallbacks(Class entityClass, Callback[] callbacks);
@Deprecated
interface CallbackRegistrar extends org.hibernate.jpa.event.spi.CallbackRegistrar {
}
void buildCallbacksForEntity(Class entityClass, CallbackRegistrar callbackRegistrar);

View File

@ -0,0 +1,17 @@
/*
* 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 http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.jpa.event.spi;
import java.io.Serializable;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
public interface CallbackDefinition extends Serializable {
Callback createCallback(ManagedBeanRegistry beanRegistry);
}

View File

@ -0,0 +1,19 @@
/*
* 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 http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.jpa.event.spi;
public interface CallbackRegistrar extends CallbackRegistry {
/**
* Register the callback against the given entity.
*
* @param entityClass The entity Class to register the Callbacks against
* @param callbacks The Callbacks to register against the given entity Class
*/
void registerCallbacks(Class entityClass, Callback[] callbacks);
}

View File

@ -29,6 +29,7 @@ import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.JoinedIterator;
import org.hibernate.internal.util.collections.SingletonIterator;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.Alias;
@ -76,6 +77,7 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
private Boolean isAbstract;
private boolean hasSubselectLoadableCollections;
private Component identifierMapper;
private java.util.List<CallbackDefinition> callbackDefinitions;
// Custom SQL
private String customSQLInsert;
@ -992,6 +994,23 @@ public abstract class PersistentClass implements AttributeContainer, Serializabl
return identifierMapper != null;
}
public void addCallbackDefinitions(java.util.List<CallbackDefinition> callbackDefinitions) {
if ( callbackDefinitions == null || callbackDefinitions.isEmpty() ) {
return;
}
if ( this.callbackDefinitions == null ) {
this.callbackDefinitions = new ArrayList<>();
}
this.callbackDefinitions.addAll( callbackDefinitions );
}
public java.util.List<CallbackDefinition> getCallbackDefinitions() {
if ( callbackDefinitions == null ) {
return Collections.emptyList();
}
return Collections.unmodifiableList( callbackDefinitions );
}
public void setIdentifierMapper(Component handle) {
this.identifierMapper = handle;
}

View File

@ -7,6 +7,8 @@
package org.hibernate.mapping;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.StringTokenizer;
@ -18,6 +20,7 @@ import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadeStyles;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.property.access.spi.Getter;
import org.hibernate.property.access.spi.PropertyAccessStrategy;
import org.hibernate.property.access.spi.PropertyAccessStrategyResolver;
@ -49,6 +52,7 @@ public class Property implements Serializable, MetaAttributable {
private PersistentClass persistentClass;
private boolean naturalIdentifier;
private boolean lob;
private java.util.List<CallbackDefinition> callbackDefinitions;
public boolean isBackRef() {
return false;
@ -360,4 +364,21 @@ public class Property implements Serializable, MetaAttributable {
this.lob = lob;
}
public void addCallbackDefinitions(java.util.List<CallbackDefinition> callbackDefinitions) {
if ( callbackDefinitions == null || callbackDefinitions.isEmpty() ) {
return;
}
if ( this.callbackDefinitions == null ) {
this.callbackDefinitions = new ArrayList<>();
}
this.callbackDefinitions.addAll( callbackDefinitions );
}
public java.util.List<CallbackDefinition> getCallbackDefinitions() {
if ( callbackDefinitions == null ) {
return Collections.emptyList();
}
return Collections.unmodifiableList( callbackDefinitions );
}
}