HHH-17993 Metamodel processing on bootstrap: avoid retrying same metamodel class name multiple times

This commit is contained in:
Sanne Grinovero 2024-04-21 22:34:55 +01:00 committed by Sanne Grinovero
parent 08127f28df
commit 8f277d4b1c
1 changed files with 24 additions and 27 deletions

View File

@ -290,8 +290,9 @@ public class MetadataContext {
LOG.trace( "Wrapping up metadata context..." ); LOG.trace( "Wrapping up metadata context..." );
} }
boolean staticMetamodelScanEnabled = final boolean staticMetamodelScanEnabled =
this.jpaStaticMetaModelPopulationSetting != JpaStaticMetaModelPopulationSetting.DISABLED; this.jpaStaticMetaModelPopulationSetting != JpaStaticMetaModelPopulationSetting.DISABLED;
final Set<String> processedMetamodelClasses = new HashSet<>();
//we need to process types from superclasses to subclasses //we need to process types from superclasses to subclasses
for ( Object mapping : orderedMappings ) { for ( Object mapping : orderedMappings ) {
@ -336,7 +337,7 @@ public class MetadataContext {
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp(); ( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
if ( staticMetamodelScanEnabled ) { if ( staticMetamodelScanEnabled ) {
populateStaticMetamodel( jpaMapping ); populateStaticMetamodel( jpaMapping, processedMetamodelClasses );
} }
} }
finally { finally {
@ -380,7 +381,7 @@ public class MetadataContext {
( (AttributeContainer<?>) jpaType ).getInFlightAccess().finishUp(); ( (AttributeContainer<?>) jpaType ).getInFlightAccess().finishUp();
if ( staticMetamodelScanEnabled ) { if ( staticMetamodelScanEnabled ) {
populateStaticMetamodel( jpaType ); populateStaticMetamodel( jpaType, processedMetamodelClasses );
} }
} }
finally { finally {
@ -420,7 +421,7 @@ public class MetadataContext {
embeddables.put( embeddable.getJavaType(), embeddable ); embeddables.put( embeddable.getJavaType(), embeddable );
if ( staticMetamodelScanEnabled ) { if ( staticMetamodelScanEnabled ) {
populateStaticMetamodel( embeddable ); populateStaticMetamodel( embeddable, processedMetamodelClasses );
} }
} }
} }
@ -648,43 +649,39 @@ public class MetadataContext {
return attributes; return attributes;
} }
private <X> void populateStaticMetamodel(ManagedDomainType<X> managedType) { private <X> void populateStaticMetamodel(ManagedDomainType<X> managedType, Set<String> processedMetamodelClassName) {
final Class<X> managedTypeClass = managedType.getJavaType(); final Class<X> managedTypeClass = managedType.getJavaType();
if ( managedTypeClass == null ) { if ( managedTypeClass == null ) {
// should indicate MAP entity mode, skip... // should indicate MAP entity mode, skip...
return; return;
} }
final String metamodelClassName = managedTypeClass.getName() + '_'; final String metamodelClassName = managedTypeClass.getName() + '_';
try { if ( processedMetamodelClassName.add( metamodelClassName ) ) {
final Class<?> metamodelClass = classLoaderService.classForName( metamodelClassName );
// we found the class; so populate it...
registerAttributes( metamodelClass, managedType );
try { try {
injectField( metamodelClass, "class_", managedType, false ); final Class<?> metamodelClass = classLoaderService.classForName( metamodelClassName );
// we found the class; so populate it...
registerAttributes( metamodelClass, managedType );
try {
injectField( metamodelClass, "class_", managedType, false );
}
catch ( NoSuchFieldException e ) {
// ignore
}
} }
catch (NoSuchFieldException e) { catch ( ClassLoadingException ignore ) {
// ignore // nothing to do...
} }
}
catch (ClassLoadingException ignore) {
// nothing to do...
}
// todo : this does not account for @MappedSuperclass, mainly because this is not being tracked in our // todo : this does not account for @MappedSuperclass, mainly because this is not being tracked in our
// internal metamodel as populated from the annotations properly // internal metamodel as populated from the annotations properly
ManagedDomainType<? super X> superType = managedType.getSuperType(); ManagedDomainType<? super X> superType = managedType.getSuperType();
if ( superType != null ) { if ( superType != null ) {
populateStaticMetamodel( superType ); populateStaticMetamodel( superType, processedMetamodelClassName );
}
} }
} }
private final Set<Class<?>> processedMetamodelClasses = new HashSet<>();
private <X> void registerAttributes(Class<?> metamodelClass, ManagedDomainType<X> managedType) { private <X> void registerAttributes(Class<?> metamodelClass, ManagedDomainType<X> managedType) {
if ( !processedMetamodelClasses.add( metamodelClass ) ) {
return;
}
// push the attributes on to the metamodel class... // push the attributes on to the metamodel class...
for ( Attribute<X, ?> attribute : managedType.getDeclaredAttributes() ) { for ( Attribute<X, ?> attribute : managedType.getDeclaredAttributes() ) {
registerAttribute( metamodelClass, attribute ); registerAttribute( metamodelClass, attribute );