Skip to content

Commit c545cee

Browse files
committed
Merge remote-tracking branch 'upstream/main' into wip/6.0_merge
2 parents 7b5e8de + 8afce5b commit c545cee

15 files changed

+282
-186
lines changed

hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java

+30-1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@
101101
import org.hibernate.id.PersistentIdentifierGenerator;
102102
import org.hibernate.internal.CoreMessageLogger;
103103
import org.hibernate.internal.util.StringHelper;
104+
import org.hibernate.jpa.event.internal.CallbackDefinitionResolverLegacyImpl;
105+
import org.hibernate.jpa.event.spi.CallbackType;
104106
import org.hibernate.loader.PropertyPath;
105107
import org.hibernate.mapping.Any;
106108
import org.hibernate.mapping.BasicValue;
@@ -837,6 +839,8 @@ else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
837839
entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Table.class ) );
838840
entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation( org.hibernate.annotations.Tables.class ) );
839841
entityBinder.processComplementaryTableDefinitions( tabAnn );
842+
843+
bindCallbacks( clazzToProcess, persistentClass, context );
840844
}
841845

842846
private static void handleTypeDescriptorRegistrations(XAnnotatedElement annotatedElement, MetadataBuildingContext context) {
@@ -1432,6 +1436,32 @@ private static void bindFilterDef(FilterDef defAnn, MetadataBuildingContext cont
14321436
context.getMetadataCollector().addFilterDefinition( def );
14331437
}
14341438

1439+
private static void bindCallbacks(XClass entityClass, PersistentClass persistentClass,
1440+
MetadataBuildingContext context) {
1441+
ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager();
1442+
1443+
for ( CallbackType callbackType : CallbackType.values() ) {
1444+
persistentClass.addCallbackDefinitions( CallbackDefinitionResolverLegacyImpl.resolveEntityCallbacks(
1445+
reflectionManager, entityClass, callbackType ) );
1446+
}
1447+
1448+
context.getMetadataCollector().addSecondPass( new SecondPass() {
1449+
@Override
1450+
public void doSecondPass(Map persistentClasses) throws MappingException {
1451+
for ( @SuppressWarnings("unchecked") Iterator<Property> propertyIterator = persistentClass.getDeclaredPropertyIterator();
1452+
propertyIterator.hasNext(); ) {
1453+
Property property = propertyIterator.next();
1454+
if ( property.isComposite() ) {
1455+
for ( CallbackType callbackType : CallbackType.values() ) {
1456+
property.addCallbackDefinitions( CallbackDefinitionResolverLegacyImpl.resolveEmbeddableCallbacks(
1457+
reflectionManager, persistentClass.getMappedClass(), property, callbackType ) );
1458+
}
1459+
}
1460+
}
1461+
}
1462+
} );
1463+
}
1464+
14351465
public static void bindFetchProfilesForClass(XClass clazzToProcess, MetadataBuildingContext context) {
14361466
bindFetchProfiles( clazzToProcess, context );
14371467
}
@@ -1476,7 +1506,6 @@ private static void bindFetchProfile(FetchProfile fetchProfileAnnotation, Metada
14761506
}
14771507
}
14781508

1479-
14801509
private static void bindDiscriminatorColumnToRootPersistentClass(
14811510
RootClass rootClass,
14821511
Ejb3DiscriminatorColumn discriminatorColumn,

hibernate-core/src/main/java/org/hibernate/event/spi/EventEngine.java

+2-34
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.util.Collection;
1010
import java.util.Collections;
1111
import java.util.HashMap;
12-
import java.util.Iterator;
1312
import java.util.Map;
1413
import java.util.function.Consumer;
1514

@@ -23,9 +22,6 @@
2322
import org.hibernate.internal.util.collections.CollectionHelper;
2423
import org.hibernate.jpa.event.internal.CallbackRegistryImplementor;
2524
import org.hibernate.jpa.event.internal.CallbacksFactory;
26-
import org.hibernate.jpa.event.spi.CallbackBuilder;
27-
import org.hibernate.mapping.PersistentClass;
28-
import org.hibernate.mapping.Property;
2925
import org.hibernate.service.spi.Stoppable;
3026

3127
/**
@@ -39,7 +35,6 @@ public class EventEngine {
3935
private final EventListenerRegistry listenerRegistry;
4036

4137
private final CallbackRegistryImplementor callbackRegistry;
42-
private final CallbackBuilder callbackBuilder;
4338

4439
public EventEngine(
4540
MetadataImplementor mappings,
@@ -48,33 +43,8 @@ public EventEngine(
4843
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4944
// resolve (JPA) callback handlers
5045

51-
this.callbackRegistry = CallbacksFactory.buildCallbackRegistry( sessionFactory.getSessionFactoryOptions() );
52-
this.callbackBuilder = CallbacksFactory.buildCallbackBuilder(
53-
sessionFactory.getSessionFactoryOptions(),
54-
sessionFactory.getServiceRegistry(),
55-
mappings.getMetadataBuildingOptions().getReflectionManager()
56-
);
57-
58-
for ( PersistentClass persistentClass : mappings.getEntityBindings() ) {
59-
if ( persistentClass.getClassName() == null ) {
60-
// we can have dynamic (non-java class) mapping
61-
continue;
62-
}
63-
64-
this.callbackBuilder.buildCallbacksForEntity( persistentClass.getMappedClass(), callbackRegistry );
65-
66-
for ( Iterator<Property> propertyIterator = persistentClass.getDeclaredPropertyIterator(); propertyIterator.hasNext(); ) {
67-
final Property property = propertyIterator.next();
68-
69-
if ( property.isComposite() ) {
70-
this.callbackBuilder.buildCallbacksForEmbeddable(
71-
property,
72-
persistentClass.getMappedClass(),
73-
callbackRegistry
74-
);
75-
}
76-
}
77-
}
46+
this.callbackRegistry = CallbacksFactory.buildCallbackRegistry( sessionFactory.getSessionFactoryOptions(),
47+
sessionFactory.getServiceRegistry(), mappings.getEntityBindings() );
7848

7949

8050
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -192,7 +162,5 @@ public void stop() {
192162
}
193163

194164
callbackRegistry.release();
195-
196-
callbackBuilder.release();
197165
}
198166
}

hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackBuilderLegacyImpl.java renamed to hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackDefinitionResolverLegacyImpl.java

+29-82
Original file line numberDiff line numberDiff line change
@@ -19,97 +19,48 @@
1919
import jakarta.persistence.MappedSuperclass;
2020
import jakarta.persistence.PersistenceException;
2121

22-
import org.hibernate.MappingException;
2322
import org.hibernate.annotations.common.reflection.ReflectionManager;
2423
import org.hibernate.annotations.common.reflection.XClass;
2524
import org.hibernate.annotations.common.reflection.XMethod;
2625
import org.hibernate.internal.util.ReflectHelper;
27-
import org.hibernate.jpa.event.spi.Callback;
28-
import org.hibernate.jpa.event.spi.CallbackBuilder;
26+
import org.hibernate.jpa.event.spi.CallbackDefinition;
2927
import org.hibernate.jpa.event.spi.CallbackType;
28+
import org.hibernate.mapping.PersistentClass;
3029
import org.hibernate.mapping.Property;
3130
import org.hibernate.property.access.spi.Getter;
32-
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
3331

3432
import org.jboss.logging.Logger;
3533

3634
/**
37-
* EntityCallbackBuilder implementation using HCANN ReflectionManager. "legacy" in that
38-
* we want to move to Jandex instead.
35+
* Resolves JPA callback definitions using a HCANN ReflectionManager.
36+
* <p>
37+
* "legacy" in that we want to move to Jandex instead.
3938
*
4039
* @author Steve Ebersole
4140
*/
42-
final class CallbackBuilderLegacyImpl implements CallbackBuilder {
43-
private static final Logger log = Logger.getLogger( CallbackBuilderLegacyImpl.class );
44-
45-
private final ManagedBeanRegistry managedBeanRegistry;
46-
private final ReflectionManager reflectionManager;
47-
48-
CallbackBuilderLegacyImpl(ManagedBeanRegistry managedBeanRegistry, ReflectionManager reflectionManager) {
49-
this.managedBeanRegistry = managedBeanRegistry;
50-
this.reflectionManager = reflectionManager;
51-
}
52-
53-
@Override
54-
public void buildCallbacksForEntity(Class entityClass, CallbackRegistrar callbackRegistrar) {
55-
for ( CallbackType callbackType : CallbackType.values() ) {
56-
if ( callbackRegistrar.hasRegisteredCallbacks( entityClass, callbackType ) ) {
57-
// this most likely means we have a class mapped multiple times using the hbm.xml
58-
// "entity name" feature
59-
if ( log.isDebugEnabled() ) {
60-
log.debugf(
61-
"CallbackRegistry reported that Class [%s] already had %s callbacks registered; " +
62-
"assuming this means the class was mapped twice " +
63-
"(using hbm.xml entity-name support) - skipping subsequent registrations",
64-
entityClass.getName(),
65-
callbackType.getCallbackAnnotation().getSimpleName()
66-
);
67-
}
68-
continue;
69-
}
70-
final Callback[] callbacks = resolveEntityCallbacks( entityClass, callbackType, reflectionManager );
71-
callbackRegistrar.registerCallbacks( entityClass, callbacks );
72-
}
73-
}
74-
75-
@Override
76-
public void buildCallbacksForEmbeddable(
77-
Property embeddableProperty, Class entityClass, CallbackRegistrar callbackRegistrar) {
78-
for ( CallbackType callbackType : CallbackType.values() ) {
79-
final Callback[] callbacks = resolveEmbeddableCallbacks(
80-
entityClass,
81-
embeddableProperty,
82-
callbackType,
83-
reflectionManager
84-
);
85-
callbackRegistrar.registerCallbacks( entityClass, callbacks );
86-
}
87-
}
88-
89-
@Override
90-
public void release() {
91-
// nothing to do
92-
}
41+
public final class CallbackDefinitionResolverLegacyImpl {
42+
private static final Logger log = Logger.getLogger( CallbackDefinitionResolverLegacyImpl.class );
9343

9444
@SuppressWarnings({"unchecked", "WeakerAccess"})
95-
public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbackType, ReflectionManager reflectionManager) {
96-
List<Callback> callbacks = new ArrayList<>();
45+
public static List<CallbackDefinition> resolveEntityCallbacks(ReflectionManager reflectionManager,
46+
XClass entityClass, CallbackType callbackType) {
47+
List<CallbackDefinition> callbackDefinitions = new ArrayList<>();
9748
List<String> callbacksMethodNames = new ArrayList<>();
9849
List<Class> orderedListeners = new ArrayList<>();
99-
XClass currentClazz = reflectionManager.toXClass( entityClass );
50+
XClass currentClazz = entityClass;
10051
boolean stopListeners = false;
10152
boolean stopDefaultListeners = false;
10253
do {
103-
Callback callback = null;
54+
CallbackDefinition callbackDefinition = null;
10455
List<XMethod> methods = currentClazz.getDeclaredMethods();
10556
for ( final XMethod xMethod : methods ) {
10657
if ( xMethod.isAnnotationPresent( callbackType.getCallbackAnnotation() ) ) {
10758
Method method = reflectionManager.toMethod( xMethod );
10859
final String methodName = method.getName();
10960
if ( !callbacksMethodNames.contains( methodName ) ) {
11061
//overridden method, remove the superclass overridden method
111-
if ( callback == null ) {
112-
callback = new EntityCallback( method, callbackType );
62+
if ( callbackDefinition == null ) {
63+
callbackDefinition = new EntityCallback.Definition( method, callbackType );
11364
Class returnType = method.getReturnType();
11465
Class[] args = method.getParameterTypes();
11566
if ( returnType != Void.TYPE || args.length != 0 ) {
@@ -127,7 +78,7 @@ public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbac
12778
entityClass.getName()
12879
);
12980
}
130-
callbacks.add( 0, callback ); //superclass first
81+
callbackDefinitions.add( 0, callbackDefinition ); //superclass first
13182
callbacksMethodNames.add( 0, methodName );
13283
}
13384
else {
@@ -168,7 +119,7 @@ public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbac
168119
}
169120

170121
for ( Class listener : orderedListeners ) {
171-
Callback callback = null;
122+
CallbackDefinition callbackDefinition = null;
172123
if ( listener != null ) {
173124
XClass xListener = reflectionManager.toXClass( listener );
174125
callbacksMethodNames = new ArrayList<>();
@@ -179,12 +130,8 @@ public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbac
179130
final String methodName = method.getName();
180131
if ( !callbacksMethodNames.contains( methodName ) ) {
181132
//overridden method, remove the superclass overridden method
182-
if ( callback == null ) {
183-
callback = new ListenerCallback(
184-
managedBeanRegistry.getBean( listener ),
185-
method,
186-
callbackType
187-
);
133+
if ( callbackDefinition == null ) {
134+
callbackDefinition = new ListenerCallback.Definition( listener, method, callbackType );
188135

189136
Class returnType = method.getReturnType();
190137
Class[] args = method.getParameterTypes();
@@ -203,7 +150,7 @@ public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbac
203150
entityClass.getName()
204151
);
205152
}
206-
callbacks.add( 0, callback ); // listeners first
153+
callbackDefinitions.add( 0, callbackDefinition ); // listeners first
207154
}
208155
else {
209156
throw new PersistenceException(
@@ -218,29 +165,29 @@ public Callback[] resolveEntityCallbacks(Class entityClass, CallbackType callbac
218165
}
219166
}
220167
}
221-
return callbacks.toArray( new Callback[callbacks.size()] );
168+
return callbackDefinitions;
222169
}
223170

224-
@SuppressWarnings({"unchecked", "WeakerAccess"})
225-
public Callback[] resolveEmbeddableCallbacks(Class entityClass, Property embeddableProperty, CallbackType callbackType, ReflectionManager reflectionManager) {
226-
171+
public static List<CallbackDefinition> resolveEmbeddableCallbacks(ReflectionManager reflectionManager,
172+
Class<?> entityClass, Property embeddableProperty,
173+
CallbackType callbackType) {
227174
final Class embeddableClass = embeddableProperty.getType().getReturnedClass();
228175
final XClass embeddableXClass = reflectionManager.toXClass( embeddableClass );
229176
final Getter embeddableGetter = embeddableProperty.getGetter( entityClass );
230-
final List<Callback> callbacks = new ArrayList<>();
177+
final List<CallbackDefinition> callbackDefinitions = new ArrayList<>();
231178
final List<String> callbacksMethodNames = new ArrayList<>();
232179
XClass currentClazz = embeddableXClass;
233180
do {
234-
Callback callback = null;
181+
CallbackDefinition callbackDefinition = null;
235182
List<XMethod> methods = currentClazz.getDeclaredMethods();
236183
for ( final XMethod xMethod : methods ) {
237184
if ( xMethod.isAnnotationPresent( callbackType.getCallbackAnnotation() ) ) {
238185
Method method = reflectionManager.toMethod( xMethod );
239186
final String methodName = method.getName();
240187
if ( !callbacksMethodNames.contains( methodName ) ) {
241188
//overridden method, remove the superclass overridden method
242-
if ( callback == null ) {
243-
callback = new EmbeddableCallback( embeddableGetter, method, callbackType );
189+
if ( callbackDefinition == null ) {
190+
callbackDefinition = new EmbeddableCallback.Definition( embeddableGetter, method, callbackType );
244191
Class returnType = method.getReturnType();
245192
Class[] args = method.getParameterTypes();
246193
if ( returnType != Void.TYPE || args.length != 0 ) {
@@ -258,7 +205,7 @@ public Callback[] resolveEmbeddableCallbacks(Class entityClass, Property embedda
258205
embeddableXClass.getName()
259206
);
260207
}
261-
callbacks.add( 0, callback ); //superclass first
208+
callbackDefinitions.add( 0, callbackDefinition ); //superclass first
262209
callbacksMethodNames.add( 0, methodName );
263210
}
264211
else {
@@ -278,7 +225,7 @@ public Callback[] resolveEmbeddableCallbacks(Class entityClass, Property embedda
278225
}
279226
while ( currentClazz != null );
280227

281-
return callbacks.toArray( new Callback[callbacks.size()] );
228+
return callbackDefinitions;
282229
}
283230

284231
private static boolean useAnnotationAnnotatedByListener;

hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImpl.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ public void registerCallbacks(Class entityClass, Callback[] callbacks) {
4141
return;
4242
}
4343

44-
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( callbacks[0].getCallbackType() );
45-
Callback[] entityCallbacks = map.get( entityClass );
46-
47-
if ( entityCallbacks != null ) {
48-
callbacks = ArrayHelper.join( entityCallbacks, callbacks );
44+
for ( Callback callback : callbacks ) {
45+
final HashMap<Class, Callback[]> map = determineAppropriateCallbackMap( callback.getCallbackType() );
46+
Callback[] entityCallbacks = map.get( entityClass );
47+
if ( entityCallbacks == null ) {
48+
entityCallbacks = new Callback[0];
49+
}
50+
entityCallbacks = ArrayHelper.join( entityCallbacks, callback );
51+
map.put( entityClass, entityCallbacks );
4952
}
50-
map.put( entityClass, callbacks );
5153
}
5254

5355
@Override

hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImplementor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
package org.hibernate.jpa.event.internal;
88

99
import org.hibernate.jpa.event.spi.CallbackBuilder;
10-
import org.hibernate.jpa.event.spi.CallbackRegistry;
10+
import org.hibernate.jpa.event.spi.CallbackRegistrar;
1111

12-
public interface CallbackRegistryImplementor extends CallbackRegistry, CallbackBuilder.CallbackRegistrar {
12+
public interface CallbackRegistryImplementor extends CallbackRegistrar, CallbackBuilder.CallbackRegistrar {
1313

1414
void release();
1515

0 commit comments

Comments
 (0)