From a9b262a8d199fab27b576a1ef285a570aeabdeb7 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Thu, 19 Sep 2024 10:47:34 +0200 Subject: [PATCH 1/4] simplify Generator instantiation lifecycle remove a bunch of unused parameters from methods in this package --- .../InFlightMetadataCollectorImpl.java | 26 ++- .../internal/GeneratorAnnotationHelper.java | 22 +-- .../boot/model/internal/GeneratorBinder.java | 69 ++----- .../IdBagIdGeneratorResolverSecondPass.java | 64 +++--- .../IdGeneratorResolverSecondPass.java | 185 ++++++++---------- .../StrictIdGeneratorResolverSecondPass.java | 102 +++++----- .../boot/model/relational/Namespace.java | 2 +- .../generator/GeneratorCreationContext.java | 8 + .../id/enhanced/SequenceStyleGenerator.java | 9 +- .../hibernate/id/enhanced/TableGenerator.java | 9 - .../internal/SessionFactoryImpl.java | 41 ++-- .../java/org/hibernate/mapping/Component.java | 10 +- .../hibernate/mapping/GeneratorSettings.java | 14 ++ .../java/org/hibernate/mapping/KeyValue.java | 9 +- .../java/org/hibernate/mapping/Property.java | 28 +-- .../org/hibernate/mapping/SimpleValue.java | 31 +-- .../AbstractCollectionPersister.java | 20 +- .../id/generators/UnnamedGeneratorTests.java | 3 +- .../auto/AutoGenerationTypeTests.java | 2 +- .../orm/test/query/hql/FunctionTests.java | 1 - 20 files changed, 317 insertions(+), 338 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 5c701d5722d1..53abd33d07ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -54,7 +54,6 @@ import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.AuxiliaryDatabaseObject; import org.hibernate.boot.model.relational.Database; -import org.hibernate.boot.model.relational.ExportableProducer; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass; @@ -81,7 +80,6 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.generator.Generator; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.collections.CollectionHelper; @@ -91,6 +89,7 @@ import org.hibernate.mapping.DenormalizedTable; import org.hibernate.mapping.FetchProfile; import org.hibernate.mapping.ForeignKey; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.Join; import org.hibernate.mapping.KeyValue; @@ -2204,15 +2203,22 @@ private void processExportableProducers() { private void handleIdentifierValueBinding( KeyValue identifierValueBinding, Dialect dialect, RootClass entityBinding, Property identifierProperty) { - // todo : store this result (back into the entity or into the KeyValue, maybe?) - // This process of instantiating the id-generator is called multiple times. - // It was done this way in the old code too, so no "regression" here; but - // it could be done better try { - final Generator generator = identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty ); - if ( generator instanceof ExportableProducer exportableProducer ) { - exportableProducer.registerExportables( getDatabase() ); - } + // this call typically caches the new Generator in the instance of KeyValue + identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty, + new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + //TODO: does not have access to property-configured default + return persistenceUnitMetadata.getDefaultCatalog(); + } + + @Override + public String getDefaultSchema() { + //TODO: does not have access to property-configured default + return persistenceUnitMetadata.getDefaultSchema(); + } + } ); } catch (MappingException e) { // ignore this for now. The reasoning being "non-reflective" binding as needed diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorAnnotationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorAnnotationHelper.java index f0c1d9ec44ac..90b952e1e002 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorAnnotationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorAnnotationHelper.java @@ -94,10 +94,11 @@ public static A findLocalizedMatch( // lastly, on the package final String packageInfoFqn = StringHelper.qualifier( idMember.getDeclaringType().getClassName() ) + ".package-info"; try { - final ClassDetails packageInfo = context.getMetadataCollector() - .getSourceModelBuildingContext() - .getClassDetailsRegistry() - .resolveClassDetails( packageInfoFqn ); + final ClassDetails packageInfo = + context.getMetadataCollector() + .getSourceModelBuildingContext() + .getClassDetailsRegistry() + .resolveClassDetails( packageInfoFqn ); for ( A generatorAnnotation : packageInfo.getRepeatedAnnotationUsages( generatorAnnotationType, sourceModelContext ) ) { if ( nameExtractor != null ) { final String registrationName = nameExtractor.apply( generatorAnnotation ); @@ -138,10 +139,7 @@ public static void handleUuidStrategy( idValue.setCustomIdGeneratorCreator( (creationContext) -> new UuidGenerator( generatorConfig, idMember ) ); } - public static void handleIdentityStrategy( - SimpleValue idValue, - MemberDetails idMember, - MetadataBuildingContext context) { + public static void handleIdentityStrategy(SimpleValue idValue) { idValue.setCustomIdGeneratorCreator( (creationContext) -> new IdentityGenerator() ); idValue.setColumnToIdentity(); } @@ -189,7 +187,6 @@ public static void handleGenericGenerator( GenericGenerator generatorConfig, PersistentClass entityMapping, SimpleValue idValue, - MemberDetails idMember, MetadataBuildingContext context) { //generator settings final Map configuration = new HashMap<>(); @@ -206,9 +203,7 @@ public static void handleGenericGenerator( GeneratorBinder.createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, determineStrategyName( generatorConfig ), configuration ), - idMember, idValue, - entityMapping, context ); } @@ -232,17 +227,14 @@ public static void handleTableGenerator( TableGenerator generatorConfig, PersistentClass entityMapping, SimpleValue idValue, - MemberDetails idMember, MetadataBuildingContext context) { final Map configuration = new HashMap<>(); applyBaselineConfiguration( generatorConfig, idValue, entityMapping.getRootClass(), context, configuration::put ); - org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generatorConfig, idValue, configuration::put ); + org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generatorConfig, configuration::put ); GeneratorBinder.createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, org.hibernate.id.enhanced.TableGenerator.class.getName(), configuration ), - idMember, idValue, - entityMapping, context ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorBinder.java index 25045913cb04..630e1c929b61 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/GeneratorBinder.java @@ -7,7 +7,6 @@ import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -46,6 +45,7 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.mapping.GeneratorCreator; +import org.hibernate.mapping.KeyValue; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.SimpleValue; import org.hibernate.models.spi.AnnotationTarget; @@ -283,22 +283,6 @@ private static GenerationType interpretGenerationType(GeneratedValue generatedVa return strategy == null ? AUTO : strategy; } - /** - * Collects definition objects for all generators defined using any of {@link TableGenerator}, - * {@link SequenceGenerator}, and {@link GenericGenerator} on the given annotated element. - */ - public static List collectIdGeneratorDefinitions( - AnnotationTarget annotatedElement, - MetadataBuildingContext context) { - final ArrayList definitions = new ArrayList<>(); - visitIdGeneratorDefinitions( - annotatedElement, - definitions::add, - context - ); - return definitions; - } - public static void visitIdGeneratorDefinitions( AnnotationTarget annotatedElement, Consumer consumer, @@ -693,7 +677,7 @@ public static void callConfigure( Generator generator, Map configuration, SimpleValue identifierValue) { - if ( generator instanceof final Configurable configurable ) { + if ( generator instanceof Configurable configurable ) { final Properties parameters = collectParameters( identifierValue, creationContext.getDatabase().getDialect(), @@ -702,6 +686,12 @@ public static void callConfigure( ); configurable.configure( creationContext, parameters ); } + if ( generator instanceof ExportableProducer exportableProducer ) { + exportableProducer.registerExportables( creationContext.getDatabase() ); + } + if ( generator instanceof Configurable configurable ) { + configurable.initialize( creationContext.getSqlStringGenerationContext() ); + } } private static void checkIdGeneratorTiming(Class annotationType, Generator generator) { @@ -726,11 +716,12 @@ private static void createIdGenerator( // NOTE: `generatedValue` is never null here final GeneratedValue generatedValue = castNonNull( idMember.getDirectAnnotationUsage( GeneratedValue.class ) ); + final InFlightMetadataCollector metadataCollector = context.getMetadataCollector(); if ( isGlobalGeneratorNameGlobal( context ) ) { // process and register any generators defined on the member. // according to JPA these are also global. - context.getMetadataCollector().getGlobalRegistrations().as( GlobalRegistrar.class ).collectIdGenerators( idMember ); - context.getMetadataCollector().addSecondPass( new StrictIdGeneratorResolverSecondPass( + metadataCollector.getGlobalRegistrations().as( GlobalRegistrar.class ).collectIdGenerators( idMember ); + metadataCollector.addSecondPass( new StrictIdGeneratorResolverSecondPass( persistentClass, idValue, idMember, @@ -738,7 +729,7 @@ private static void createIdGenerator( ) ); } else { - context.getMetadataCollector().addSecondPass( new IdGeneratorResolverSecondPass( + metadataCollector.addSecondPass( new IdGeneratorResolverSecondPass( persistentClass, idValue, idMember, @@ -750,7 +741,6 @@ private static void createIdGenerator( public static void createGeneratorFrom( IdentifierGeneratorDefinition defaultedGenerator, - MemberDetails idMember, SimpleValue idValue, Map configuration, MetadataBuildingContext context) { @@ -766,11 +756,6 @@ public static void createGeneratorFrom( if ( identifierGenerator instanceof IdentityGenerator) { idValue.setColumnToIdentity(); } - - if ( identifierGenerator instanceof ExportableProducer exportableProducer ) { - exportableProducer.registerExportables( creationContext.getDatabase() ); - } - return identifierGenerator; } ); } @@ -778,31 +763,22 @@ public static void createGeneratorFrom( public static void createGeneratorFrom( IdentifierGeneratorDefinition defaultedGenerator, - MemberDetails idMember, SimpleValue idValue, - PersistentClass persistentClass, MetadataBuildingContext context) { createGeneratorFrom( defaultedGenerator, - idMember, idValue, - buildConfigurationMap( defaultedGenerator, idValue, persistentClass ), + buildConfigurationMap( idValue ), context ); } - public static Map buildConfigurationMap( - IdentifierGeneratorDefinition defaultedGenerator, - SimpleValue idValue, - PersistentClass persistentClass) { + private static Map buildConfigurationMap(KeyValue idValue) { final Map configuration = new HashMap<>(); - configuration.put( PersistentIdentifierGenerator.TABLE, idValue.getTable().getName() ); - if ( idValue.getColumnSpan() == 1 ) { - configuration.put( PersistentIdentifierGenerator.PK, idValue.getColumns().get( 0).getName() ); + configuration.put( PersistentIdentifierGenerator.PK, idValue.getColumns().get(0).getName() ); } - return configuration; } @@ -941,15 +917,12 @@ static GeneratorCreator createValueGeneratorFromAnnotations( final List generatorAnnotations = property.getMetaAnnotated( ValueGenerationType.class, context.getMetadataCollector().getSourceModelBuildingContext() ); - switch ( generatorAnnotations.size() ) { - case 0: - return null; - case 1: - return generatorCreator( property, generatorAnnotations.get(0), beanContainer( context ) ); - default: - throw new AnnotationException( "Property '" + qualify( holder.getPath(), propertyName ) - + "' has too many generator annotations: " + generatorAnnotations ); - } + return switch ( generatorAnnotations.size() ) { + case 0 -> null; + case 1 -> generatorCreator( property, generatorAnnotations.get(0), beanContainer( context ) ); + default -> throw new AnnotationException( "Property '" + qualify( holder.getPath(), propertyName ) + + "' has too many generator annotations: " + generatorAnnotations ); + }; } public static void applyIfNotEmpty(String name, String value, BiConsumer consumer) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdBagIdGeneratorResolverSecondPass.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdBagIdGeneratorResolverSecondPass.java index db83c3fa3842..6fa5ee085257 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdBagIdGeneratorResolverSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdBagIdGeneratorResolverSecondPass.java @@ -15,6 +15,7 @@ import org.hibernate.boot.models.spi.GlobalRegistrations; import org.hibernate.boot.models.spi.SequenceGeneratorRegistration; import org.hibernate.boot.models.spi.TableGeneratorRegistration; +import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.generator.Generator; import org.hibernate.id.PersistentIdentifierGenerator; @@ -68,7 +69,7 @@ public void doSecondPass(Map idGeneratorDefinitionMap) final GeneratedValue generatedValue = idAttributeMember.getDirectAnnotationUsage( GeneratedValue.class ); switch ( generatedValue.strategy() ) { case UUID -> GeneratorAnnotationHelper.handleUuidStrategy( idValue, idAttributeMember, buildingContext ); - case IDENTITY -> GeneratorAnnotationHelper.handleIdentityStrategy( idValue, idAttributeMember, buildingContext ); + case IDENTITY -> GeneratorAnnotationHelper.handleIdentityStrategy( idValue ); case SEQUENCE -> handleSequenceStrategy( generatorName, idValue, @@ -80,15 +81,12 @@ public void doSecondPass(Map idGeneratorDefinitionMap) entityMapping, idValue, idAttributeMember, - generatedValue, buildingContext ); case AUTO -> handleAutoStrategy( generatorName, - entityMapping, idValue, idAttributeMember, - generatedValue, buildingContext ); } @@ -99,17 +97,18 @@ private void handleTableStrategy( PersistentClass entityMapping, SimpleValue idValue, MemberDetails idAttributeMember, - GeneratedValue generatedValue, MetadataBuildingContext buildingContext) { - final GlobalRegistrations globalRegistrations = buildingContext.getMetadataCollector().getGlobalRegistrations(); - final TableGeneratorRegistration globalTableGenerator = globalRegistrations.getTableGeneratorRegistrations().get( generatorName ); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + final GlobalRegistrations globalRegistrations = metadataCollector.getGlobalRegistrations(); + + final TableGeneratorRegistration globalTableGenerator = + globalRegistrations.getTableGeneratorRegistrations().get( generatorName ); if ( globalTableGenerator != null ) { handleTableGenerator( generatorName, globalTableGenerator.configuration(), configuration, idValue, - idAttributeMember, buildingContext ); return; @@ -123,16 +122,15 @@ private void handleTableStrategy( buildingContext ); if ( localizedTableMatch != null ) { - handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, idAttributeMember, buildingContext ); + handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, buildingContext ); return; } GeneratorAnnotationHelper.handleTableGenerator( generatorName, - new TableGeneratorJpaAnnotation( buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new TableGeneratorJpaAnnotation( metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, - idAttributeMember, buildingContext ); } @@ -142,16 +140,17 @@ private void handleSequenceStrategy( SimpleValue idValue, MemberDetails idAttributeMember, MetadataBuildingContext buildingContext) { - final GlobalRegistrations globalRegistrations = buildingContext.getMetadataCollector().getGlobalRegistrations(); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + final GlobalRegistrations globalRegistrations = metadataCollector.getGlobalRegistrations(); - final SequenceGeneratorRegistration globalSequenceGenerator = globalRegistrations.getSequenceGeneratorRegistrations().get( generatorName ); + final SequenceGeneratorRegistration globalSequenceGenerator = + globalRegistrations.getSequenceGeneratorRegistrations().get( generatorName ); if ( globalSequenceGenerator != null ) { handleSequenceGenerator( generatorName, globalSequenceGenerator.configuration(), configuration, idValue, - idAttributeMember, buildingContext ); return; @@ -165,57 +164,56 @@ private void handleSequenceStrategy( buildingContext ); if ( localizedSequencedMatch != null ) { - handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, idAttributeMember, buildingContext ); + handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, buildingContext ); return; } handleSequenceGenerator( generatorName, - new SequenceGeneratorJpaAnnotation( buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new SequenceGeneratorJpaAnnotation( metadataCollector.getSourceModelBuildingContext() ), configuration, idValue, - idAttributeMember, buildingContext ); } private void handleAutoStrategy( String generatorName, - PersistentClass entityMapping, SimpleValue idValue, MemberDetails idAttributeMember, - GeneratedValue generatedValue, MetadataBuildingContext buildingContext) { - final GlobalRegistrations globalRegistrations = buildingContext.getMetadataCollector().getGlobalRegistrations(); + final GlobalRegistrations globalRegistrations = + buildingContext.getMetadataCollector().getGlobalRegistrations(); - final SequenceGeneratorRegistration globalSequenceGenerator = globalRegistrations.getSequenceGeneratorRegistrations().get( generatorName ); + final SequenceGeneratorRegistration globalSequenceGenerator = + globalRegistrations.getSequenceGeneratorRegistrations().get( generatorName ); if ( globalSequenceGenerator != null ) { handleSequenceGenerator( generatorName, globalSequenceGenerator.configuration(), configuration, idValue, - idAttributeMember, buildingContext ); return; } - final TableGeneratorRegistration globalTableGenerator = globalRegistrations.getTableGeneratorRegistrations().get( generatorName ); + final TableGeneratorRegistration globalTableGenerator = + globalRegistrations.getTableGeneratorRegistrations().get( generatorName ); if ( globalTableGenerator != null ) { handleTableGenerator( generatorName, globalTableGenerator.configuration(), configuration, idValue, - idAttributeMember, buildingContext ); return; } - final Class legacyNamedGenerator = GeneratorStrategies.mapLegacyNamedGenerator( generatorName, idValue ); + final Class legacyNamedGenerator = + GeneratorStrategies.mapLegacyNamedGenerator( generatorName, idValue ); if ( legacyNamedGenerator != null ) { //generator settings if ( idValue.getColumnSpan() == 1 ) { @@ -223,7 +221,6 @@ private void handleAutoStrategy( } createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, legacyNamedGenerator.getName(), configuration ), - idAttributeMember, idValue, (Map) configuration, buildingContext @@ -231,7 +228,6 @@ private void handleAutoStrategy( return; } - final SequenceGenerator localizedSequencedMatch = GeneratorAnnotationHelper.findLocalizedMatch( JpaAnnotations.SEQUENCE_GENERATOR, idAttributeMember, @@ -240,7 +236,7 @@ private void handleAutoStrategy( buildingContext ); if ( localizedSequencedMatch != null ) { - handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, idAttributeMember, buildingContext ); + handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, buildingContext ); return; } @@ -252,7 +248,7 @@ private void handleAutoStrategy( buildingContext ); if ( localizedTableMatch != null ) { - handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, idAttributeMember, buildingContext ); + handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, buildingContext ); return; } @@ -264,19 +260,15 @@ public static void handleSequenceGenerator( SequenceGenerator generatorConfig, Map configuration, SimpleValue idValue, - MemberDetails idMember, MetadataBuildingContext context) { applyBaselineConfiguration( generatorConfig, idValue, null, context, configuration::put ); - SequenceStyleGenerator.applyConfiguration( generatorConfig, idValue, configuration::put ); - + SequenceStyleGenerator.applyConfiguration( generatorConfig, configuration::put ); createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, SequenceStyleGenerator.class.getName(), configuration ), - idMember, idValue, (Map) configuration, context ); - } public static void handleTableGenerator( @@ -284,14 +276,12 @@ public static void handleTableGenerator( TableGenerator generatorConfig, Map configuration, SimpleValue idValue, - MemberDetails idMember, MetadataBuildingContext context) { GeneratorAnnotationHelper.applyBaselineConfiguration( generatorConfig, idValue, null, context, configuration::put ); - org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generatorConfig, idValue, configuration::put ); + org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generatorConfig, configuration::put ); createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, org.hibernate.id.enhanced.TableGenerator.class.getName(), configuration ), - idMember, idValue, (Map) configuration, context diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdGeneratorResolverSecondPass.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdGeneratorResolverSecondPass.java index 2bee2dde317a..9ae2ddf1e4f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdGeneratorResolverSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/IdGeneratorResolverSecondPass.java @@ -15,15 +15,14 @@ import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.IdGeneratorType; import org.hibernate.boot.model.IdentifierGeneratorDefinition; -import org.hibernate.boot.model.relational.ExportableProducer; import org.hibernate.boot.models.HibernateAnnotations; import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.models.spi.GenericGeneratorRegistration; +import org.hibernate.boot.models.spi.GlobalRegistrations; import org.hibernate.boot.models.spi.SequenceGeneratorRegistration; import org.hibernate.boot.models.spi.TableGeneratorRegistration; -import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.StandardConverters; import org.hibernate.generator.Generator; @@ -43,7 +42,9 @@ import jakarta.persistence.TableGenerator; import static org.hibernate.boot.model.internal.GeneratorBinder.callConfigure; +import static org.hibernate.boot.model.internal.GeneratorBinder.instantiateGenerator; import static org.hibernate.boot.model.internal.GeneratorStrategies.mapLegacyNamedGenerator; +import static org.hibernate.cfg.MappingSettings.ID_DB_STRUCTURE_NAMING_STRATEGY; import static org.hibernate.id.IdentifierGenerator.GENERATOR_NAME; import static org.hibernate.id.OptimizableGenerator.INCREMENT_PARAM; @@ -78,7 +79,7 @@ public IdGeneratorResolverSecondPass( public void doSecondPass(Map persistentClasses) throws MappingException { switch ( generatedValue.strategy() ) { case UUID -> GeneratorAnnotationHelper.handleUuidStrategy( idValue, idMember, buildingContext ); - case IDENTITY -> GeneratorAnnotationHelper.handleIdentityStrategy( idValue, idMember, buildingContext ); + case IDENTITY -> GeneratorAnnotationHelper.handleIdentityStrategy( idValue ); case SEQUENCE -> handleSequenceStrategy(); case TABLE -> handleTableStrategy(); case AUTO -> handleAutoStrategy(); @@ -113,62 +114,65 @@ private void handleUnnamedSequenceGenerator() { } private void handleNamedSequenceGenerator() { + final String generator = generatedValue.generator(); + final SequenceGenerator localizedMatch = GeneratorAnnotationHelper.findLocalizedMatch( JpaAnnotations.SEQUENCE_GENERATOR, idMember, SequenceGenerator::name, - generatedValue.generator(), + generator, buildingContext ); if ( localizedMatch != null ) { - handleSequenceGenerator( generatedValue.generator(), localizedMatch ); + handleSequenceGenerator( generator, localizedMatch ); return; } // look for the matching global registration, if one. - final SequenceGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( generatedValue.generator() ); + final SequenceGeneratorRegistration globalMatch = + buildingContext.getMetadataCollector() + .getGlobalRegistrations() + .getSequenceGeneratorRegistrations() + .get( generator ); if ( globalMatch != null ) { - handleSequenceGenerator( generatedValue.generator(), globalMatch.configuration() ); + handleSequenceGenerator( generator, globalMatch.configuration() ); return; } validateSequenceGeneration(); - handleSequenceGenerator( generatedValue.generator(), null ); + handleSequenceGenerator( generator, null ); } private void validateSequenceGeneration() { // basically, make sure there is neither a TableGenerator nor GenericGenerator with this name - final TableGeneratorRegistration globalTableMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( generatedValue.generator() ); + final GlobalRegistrations globalRegistrations = + buildingContext.getMetadataCollector().getGlobalRegistrations(); + final String generator = generatedValue.generator(); + + final TableGeneratorRegistration globalTableMatch = + globalRegistrations.getTableGeneratorRegistrations().get( generator ); if ( globalTableMatch != null ) { throw new MappingException( String.format( Locale.ROOT, "@GeneratedValue for %s (%s) specified SEQUENCE generation, but referred to a @TableGenerator", entityMapping.getEntityName(), - generatedValue.generator() + generator ) ); } - final GenericGeneratorRegistration globalGenericMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getGenericGeneratorRegistrations() - .get( generatedValue.generator() ); + final GenericGeneratorRegistration globalGenericMatch = + globalRegistrations.getGenericGeneratorRegistrations().get( generator ); if ( globalGenericMatch != null ) { throw new MappingException( String.format( Locale.ROOT, "@GeneratedValue for %s (%s) specified SEQUENCE generation, but referred to a @GenericGenerator", entityMapping.getEntityName(), - generatedValue.generator() + generator ) ); } @@ -193,71 +197,67 @@ private void handleUnnamedTableGenerator() { null, buildingContext ); - if ( localizedMatch != null ) { - handleTableGenerator( null, localizedMatch ); - return; - } - - handleTableGenerator( null, null ); + handleTableGenerator( null, localizedMatch ); } private void handleNamedTableGenerator() { + final String generator = generatedValue.generator(); + final TableGenerator localizedTableMatch = GeneratorAnnotationHelper.findLocalizedMatch( JpaAnnotations.TABLE_GENERATOR, idMember, TableGenerator::name, - generatedValue.generator(), + generator, buildingContext ); if ( localizedTableMatch != null ) { - handleTableGenerator( generatedValue.generator(), localizedTableMatch ); + handleTableGenerator( generator, localizedTableMatch ); return; } // look for the matching global registration, if one. - final TableGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( generatedValue.generator() ); + final TableGeneratorRegistration globalMatch = + buildingContext.getMetadataCollector().getGlobalRegistrations() + .getTableGeneratorRegistrations().get( generator ); if ( globalMatch != null ) { - handleTableGenerator( generatedValue.generator(), globalMatch.configuration() ); + handleTableGenerator( generator, globalMatch.configuration() ); return; } validateTableGeneration(); - handleTableGenerator( generatedValue.generator(), null ); + handleTableGenerator( generator, null ); } private void validateTableGeneration() { // basically, make sure there is neither a SequenceGenerator nor a GenericGenerator with this name - final SequenceGeneratorRegistration globalSequenceMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( generatedValue.generator() ); + final GlobalRegistrations globalRegistrations = + buildingContext.getMetadataCollector().getGlobalRegistrations(); + final String generator = generatedValue.generator(); + + final SequenceGeneratorRegistration globalSequenceMatch = + globalRegistrations.getSequenceGeneratorRegistrations().get( generator ); if ( globalSequenceMatch != null ) { throw new MappingException( String.format( Locale.ROOT, "@GeneratedValue for %s (%s) specified TABLE generation, but referred to a @SequenceGenerator", entityMapping.getEntityName(), - generatedValue.generator() + generator ) ); } - final GenericGeneratorRegistration globalGenericMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getGenericGeneratorRegistrations() - .get( generatedValue.generator() ); + final GenericGeneratorRegistration globalGenericMatch = + globalRegistrations.getGenericGeneratorRegistrations().get( generator ); if ( globalGenericMatch != null ) { throw new MappingException( String.format( Locale.ROOT, "@GeneratedValue for %s (%s) specified TABLE generation, but referred to a @GenericGenerator", entityMapping.getEntityName(), - generatedValue.generator() + generator ) ); } @@ -312,7 +312,6 @@ private void handleUnnamedAutoGenerator() { localizedGenericMatch, entityMapping, idValue, - idMember, buildingContext ); return; @@ -336,34 +335,35 @@ private void handleNamedAutoGenerator() { return; } - final Class legacyNamedGenerator = mapLegacyNamedGenerator( generatedValue.generator(), buildingContext ); + final String generator = generatedValue.generator(); + final Class legacyNamedGenerator = mapLegacyNamedGenerator( generator, buildingContext ); if ( legacyNamedGenerator != null ) { //generator settings GeneratorBinder.createGeneratorFrom( - new IdentifierGeneratorDefinition( generatedValue.generator(), legacyNamedGenerator.getName() ), - idMember, + new IdentifierGeneratorDefinition( generator, legacyNamedGenerator.getName() ), idValue, - entityMapping, buildingContext ); return; } - final List metaAnnotated = idMember.getMetaAnnotated( IdGeneratorType.class, buildingContext.getMetadataCollector().getSourceModelBuildingContext() ); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + final List metaAnnotated = + idMember.getMetaAnnotated( IdGeneratorType.class, metadataCollector.getSourceModelBuildingContext() ); if ( CollectionHelper.size( metaAnnotated ) > 0 ) { final Annotation generatorAnnotation = metaAnnotated.get( 0 ); final IdGeneratorType markerAnnotation = generatorAnnotation.annotationType().getAnnotation( IdGeneratorType.class ); idValue.setCustomIdGeneratorCreator( (creationContext) -> { final BeanContainer beanContainer = GeneratorBinder.beanContainer( buildingContext ); - final Generator identifierGenerator = GeneratorBinder.instantiateGenerator( + final Generator identifierGenerator = instantiateGenerator( beanContainer, markerAnnotation.value() ); final Map configuration = new HashMap<>(); GeneratorParameters.collectParameters( idValue, - buildingContext.getMetadataCollector().getDatabase().getDialect(), + metadataCollector.getDatabase().getDialect(), entityMapping.getRootClass(), configuration::put ); @@ -379,21 +379,22 @@ private void handleNamedAutoGenerator() { return; } - handleSequenceGenerator( generatedValue.generator(), null ); + handleSequenceGenerator(generator, null ); } private boolean handleAsLocalAutoGenerator() { - assert !generatedValue.generator().isEmpty(); + final String generator = generatedValue.generator(); + assert !generator.isEmpty(); final SequenceGenerator localizedSequenceMatch = GeneratorAnnotationHelper.findLocalizedMatch( JpaAnnotations.SEQUENCE_GENERATOR, idMember, SequenceGenerator::name, - generatedValue.generator(), + generator, buildingContext ); if ( localizedSequenceMatch != null ) { - handleSequenceGenerator( generatedValue.generator(), localizedSequenceMatch ); + handleSequenceGenerator( generator, localizedSequenceMatch ); return true; } @@ -401,11 +402,11 @@ private boolean handleAsLocalAutoGenerator() { JpaAnnotations.TABLE_GENERATOR, idMember, TableGenerator::name, - generatedValue.generator(), + generator, buildingContext ); if ( localizedTableMatch != null ) { - handleTableGenerator( generatedValue.generator(), localizedTableMatch ); + handleTableGenerator(generator, localizedTableMatch ); return true; } @@ -413,16 +414,15 @@ private boolean handleAsLocalAutoGenerator() { HibernateAnnotations.GENERIC_GENERATOR, idMember, GenericGenerator::name, - generatedValue.generator(), + generator, buildingContext ); if ( localizedGenericMatch != null ) { GeneratorAnnotationHelper.handleGenericGenerator( - generatedValue.generator(), + generator, localizedGenericMatch, entityMapping, idValue, - idMember, buildingContext ); return true; @@ -432,35 +432,32 @@ private boolean handleAsLocalAutoGenerator() { } private boolean handleAsNamedGlobalAutoGenerator() { - final SequenceGeneratorRegistration globalSequenceMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( generatedValue.generator() ); + final GlobalRegistrations globalRegistrations = + buildingContext.getMetadataCollector().getGlobalRegistrations(); + final String generator = generatedValue.generator(); + + final SequenceGeneratorRegistration globalSequenceMatch = + globalRegistrations.getSequenceGeneratorRegistrations().get( generator ); if ( globalSequenceMatch != null ) { - handleSequenceGenerator( generatedValue.generator(), globalSequenceMatch.configuration() ); + handleSequenceGenerator( generator, globalSequenceMatch.configuration() ); return true; } - final TableGeneratorRegistration globalTableMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( generatedValue.generator() ); + final TableGeneratorRegistration globalTableMatch = + globalRegistrations.getTableGeneratorRegistrations().get( generator ); if ( globalTableMatch != null ) { - handleTableGenerator( generatedValue.generator(), globalTableMatch.configuration() ); + handleTableGenerator( generator, globalTableMatch.configuration() ); return true; } - final GenericGeneratorRegistration globalGenericMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getGenericGeneratorRegistrations() - .get( generatedValue.generator() ); + final GenericGeneratorRegistration globalGenericMatch = + globalRegistrations.getGenericGeneratorRegistrations().get( generator ); if ( globalGenericMatch != null ) { GeneratorAnnotationHelper.handleGenericGenerator( - generatedValue.generator(), + generator, globalGenericMatch.configuration(), entityMapping, idValue, - idMember, buildingContext ); return true; @@ -470,8 +467,7 @@ private boolean handleAsNamedGlobalAutoGenerator() { } private void handleSequenceGenerator(String nameFromGeneratedValue, SequenceGenerator generator) { - final Map configuration = extractConfiguration( nameFromGeneratedValue, generator ); - createGeneratorFrom( SequenceStyleGenerator.class, configuration ); + createGeneratorFrom( SequenceStyleGenerator.class, extractConfiguration( nameFromGeneratedValue, generator ) ); } private Map extractConfiguration(String nameFromGenerated, SequenceGenerator generator) { @@ -486,7 +482,7 @@ else if ( nameFromGenerated != null ) { applyCommonConfiguration( configuration, generator ); if ( generator != null ) { - SequenceStyleGenerator.applyConfiguration( generator, idValue, configuration::put ); + SequenceStyleGenerator.applyConfiguration( generator, configuration::put ); } return configuration; @@ -511,13 +507,11 @@ private static int fallbackAllocationSize(MetadataBuildingContext buildingContex // here should be 50. As a migration aid, under the assumption that one of the legacy // naming-strategies are used in such cases, we revert to the old default; otherwise we // use the compliant value. - final StandardServiceRegistry serviceRegistry = buildingContext.getBootstrapContext().getServiceRegistry(); - final ConfigurationService configService = serviceRegistry.requireService( ConfigurationService.class ); - final String idNamingStrategy = configService.getSetting( - AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY, - StandardConverters.STRING, - null - ); + final ConfigurationService configService = + buildingContext.getBootstrapContext().getServiceRegistry() + .requireService( ConfigurationService.class ); + final String idNamingStrategy = + configService.getSetting( ID_DB_STRUCTURE_NAMING_STRATEGY, StandardConverters.STRING ); if ( LegacyNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy ) || LegacyNamingStrategy.class.getName().equals( idNamingStrategy ) || SingleNamingStrategy.STRATEGY_NAME.equals( idNamingStrategy ) @@ -530,8 +524,8 @@ private static int fallbackAllocationSize(MetadataBuildingContext buildingContex } private void handleTableGenerator(String nameFromGeneratedValue, TableGenerator generator) { - final Map configuration = extractConfiguration( nameFromGeneratedValue, generator ); - createGeneratorFrom( org.hibernate.id.enhanced.TableGenerator.class, configuration ); + createGeneratorFrom( org.hibernate.id.enhanced.TableGenerator.class, + extractConfiguration( nameFromGeneratedValue, generator ) ); } private Map extractConfiguration(String nameFromGenerated, TableGenerator generator) { @@ -546,7 +540,7 @@ else if ( nameFromGenerated != null ) { applyCommonConfiguration( configuration, generator ); if ( generator != null ) { - org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generator, idValue, configuration::put ); + org.hibernate.id.enhanced.TableGenerator.applyConfiguration( generator, configuration::put ); } return configuration; @@ -557,16 +551,11 @@ private void createGeneratorFrom( Map configuration) { final BeanContainer beanContainer = GeneratorBinder.beanContainer( buildingContext ); idValue.setCustomIdGeneratorCreator( (creationContext) -> { - final Generator identifierGenerator = GeneratorBinder.instantiateGenerator( beanContainer, generatorClass ); + final Generator identifierGenerator = instantiateGenerator( beanContainer, generatorClass ); callConfigure( creationContext, identifierGenerator, configuration, idValue ); if ( identifierGenerator instanceof IdentityGenerator ) { idValue.setColumnToIdentity(); } - - // if we get here we have either a sequence or table generator, - // both of which are ExportableProducers - ( (ExportableProducer) identifierGenerator ).registerExportables( creationContext.getDatabase() ); - return identifierGenerator; } ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/StrictIdGeneratorResolverSecondPass.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/StrictIdGeneratorResolverSecondPass.java index 381bc41f0371..f6ef3da0b529 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/StrictIdGeneratorResolverSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/StrictIdGeneratorResolverSecondPass.java @@ -14,8 +14,10 @@ import org.hibernate.boot.models.annotations.internal.SequenceGeneratorJpaAnnotation; import org.hibernate.boot.models.annotations.internal.TableGeneratorJpaAnnotation; import org.hibernate.boot.models.spi.GenericGeneratorRegistration; +import org.hibernate.boot.models.spi.GlobalRegistrations; import org.hibernate.boot.models.spi.SequenceGeneratorRegistration; import org.hibernate.boot.models.spi.TableGeneratorRegistration; +import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.dialect.Dialect; import org.hibernate.generator.Generator; @@ -31,6 +33,7 @@ import static org.hibernate.boot.model.internal.GeneratorAnnotationHelper.*; import static org.hibernate.boot.model.internal.GeneratorAnnotationHelper.handleUuidStrategy; import static org.hibernate.boot.model.internal.GeneratorParameters.identityTablesString; +import static org.hibernate.boot.model.internal.GeneratorStrategies.mapLegacyNamedGenerator; import static org.hibernate.id.IdentifierGenerator.ENTITY_NAME; import static org.hibernate.id.IdentifierGenerator.GENERATOR_NAME; import static org.hibernate.id.IdentifierGenerator.JPA_ENTITY_NAME; @@ -77,7 +80,7 @@ public void doSecondPass(Map persistentClasses) throws final GeneratedValue generatedValue = idMember.getDirectAnnotationUsage( GeneratedValue.class ); switch ( generatedValue.strategy() ) { case UUID -> handleUuidStrategy( idValue, idMember, buildingContext ); - case IDENTITY -> handleIdentityStrategy( idValue, idMember, buildingContext ); + case IDENTITY -> handleIdentityStrategy( idValue ); case SEQUENCE -> handleSequenceStrategy( generatedValue ); case TABLE -> handleTableStrategy( generatedValue ); case AUTO -> handleAutoStrategy( generatedValue ); @@ -94,11 +97,12 @@ private void handleSequenceStrategy(GeneratedValue generatedValue) { } private void handleUnnamedSequenceGenerator() { + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + // according to the spec, this should locate a generator with the same name as the entity-name - final SequenceGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( entityMapping.getJpaEntityName() ); + final SequenceGeneratorRegistration globalMatch = + metadataCollector.getGlobalRegistrations().getSequenceGeneratorRegistrations() + .get( entityMapping.getJpaEntityName() ); if ( globalMatch != null ) { handleSequenceGenerator( entityMapping.getJpaEntityName(), @@ -113,7 +117,7 @@ private void handleUnnamedSequenceGenerator() { handleSequenceGenerator( entityMapping.getJpaEntityName(), - new SequenceGeneratorJpaAnnotation( buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new SequenceGeneratorJpaAnnotation( metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, idMember, @@ -122,10 +126,11 @@ private void handleUnnamedSequenceGenerator() { } private void handleNamedSequenceGenerator(GeneratedValue generatedValue) { - final SequenceGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( generatedValue.generator() ); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + + final SequenceGeneratorRegistration globalMatch = + metadataCollector.getGlobalRegistrations() + .getSequenceGeneratorRegistrations().get( generatedValue.generator() ); if ( globalMatch != null ) { handleSequenceGenerator( generatedValue.generator(), @@ -140,7 +145,7 @@ private void handleNamedSequenceGenerator(GeneratedValue generatedValue) { handleSequenceGenerator( generatedValue.generator(), - new SequenceGeneratorJpaAnnotation( generatedValue.generator(), buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new SequenceGeneratorJpaAnnotation( generatedValue.generator(), metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, idMember, @@ -158,17 +163,17 @@ private void handleTableStrategy(GeneratedValue generatedValue) { } private void handleUnnamedTableGenerator() { - final TableGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( entityMapping.getJpaEntityName() ); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + + final TableGeneratorRegistration globalMatch = + metadataCollector.getGlobalRegistrations().getTableGeneratorRegistrations() + .get( entityMapping.getJpaEntityName() ); if ( globalMatch != null ) { handleTableGenerator( entityMapping.getJpaEntityName(), globalMatch.configuration(), entityMapping, idValue, - idMember, buildingContext ); return; @@ -176,26 +181,25 @@ private void handleUnnamedTableGenerator() { handleTableGenerator( entityMapping.getJpaEntityName(), - new TableGeneratorJpaAnnotation( buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new TableGeneratorJpaAnnotation( metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, - idMember, buildingContext ); } private void handleNamedTableGenerator(GeneratedValue generatedValue) { - final TableGeneratorRegistration globalMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( generatedValue.generator() ); + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + + final TableGeneratorRegistration globalMatch = + metadataCollector.getGlobalRegistrations().getTableGeneratorRegistrations() + .get( generatedValue.generator() ); if ( globalMatch != null ) { handleTableGenerator( generatedValue.generator(), globalMatch.configuration(), entityMapping, idValue, - idMember, buildingContext ); @@ -204,27 +208,22 @@ private void handleNamedTableGenerator(GeneratedValue generatedValue) { handleTableGenerator( generatedValue.generator(), - new TableGeneratorJpaAnnotation( generatedValue.generator(), buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new TableGeneratorJpaAnnotation( generatedValue.generator(), metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, - idMember, buildingContext ); } private void handleAutoStrategy(GeneratedValue generatedValue) { - final String globalRegistrationName; - if ( generatedValue.generator().isEmpty() ) { - globalRegistrationName = entityMapping.getJpaEntityName(); - } - else { - globalRegistrationName = generatedValue.generator(); - } + final String generator = generatedValue.generator(); + final String globalRegistrationName = generator.isEmpty() ? entityMapping.getJpaEntityName() : generator; + + final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); + final GlobalRegistrations globalRegistrations = metadataCollector.getGlobalRegistrations(); - final SequenceGeneratorRegistration globalSequenceMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getSequenceGeneratorRegistrations() - .get( globalRegistrationName ); + final SequenceGeneratorRegistration globalSequenceMatch = + globalRegistrations.getSequenceGeneratorRegistrations().get( globalRegistrationName ); if ( globalSequenceMatch != null ) { handleSequenceGenerator( globalRegistrationName, @@ -237,55 +236,48 @@ private void handleAutoStrategy(GeneratedValue generatedValue) { return; } - final TableGeneratorRegistration globalTableMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getTableGeneratorRegistrations() - .get( globalRegistrationName ); + final TableGeneratorRegistration globalTableMatch = + globalRegistrations.getTableGeneratorRegistrations().get( globalRegistrationName ); if ( globalTableMatch != null ) { handleTableGenerator( globalRegistrationName, globalTableMatch.configuration(), entityMapping, idValue, - idMember, buildingContext ); return; } - final GenericGeneratorRegistration globalGenericMatch = buildingContext.getMetadataCollector() - .getGlobalRegistrations() - .getGenericGeneratorRegistrations() - .get( globalRegistrationName ); + final GenericGeneratorRegistration globalGenericMatch = + globalRegistrations.getGenericGeneratorRegistrations().get( globalRegistrationName ); if ( globalGenericMatch != null ) { handleGenericGenerator( globalRegistrationName, globalGenericMatch.configuration(), entityMapping, idValue, - idMember, buildingContext ); return; } // Implicit handling of UUID generation - if ( idMember.getType().isImplementor( UUID.class ) - || idMember.getType().isImplementor( String.class )) { + if ( idMember.getType().isImplementor( UUID.class ) + || idMember.getType().isImplementor( String.class ) ) { handleUuidStrategy( idValue, idMember, buildingContext ); return; } // Handle a few legacy Hibernate generators... - if ( !generatedValue.generator().isEmpty() ) { - final Class legacyNamedGenerator = GeneratorStrategies.mapLegacyNamedGenerator( generatedValue.generator(), idValue ); + if ( !generator.isEmpty() ) { + final Class legacyNamedGenerator = mapLegacyNamedGenerator( generator, idValue ); if ( legacyNamedGenerator != null ) { final Map configuration = buildLegacyGeneratorConfig(); //noinspection unchecked,rawtypes GeneratorBinder.createGeneratorFrom( - new IdentifierGeneratorDefinition( generatedValue.generator(), legacyNamedGenerator.getName(), configuration ), - idMember, + new IdentifierGeneratorDefinition( generator, legacyNamedGenerator.getName(), configuration ), idValue, (Map) configuration, buildingContext @@ -296,7 +288,7 @@ private void handleAutoStrategy(GeneratedValue generatedValue) { handleSequenceGenerator( globalRegistrationName, - new SequenceGeneratorJpaAnnotation( generatedValue.generator(), buildingContext.getMetadataCollector().getSourceModelBuildingContext() ), + new SequenceGeneratorJpaAnnotation( generator, metadataCollector.getSourceModelBuildingContext() ), entityMapping, idValue, idMember, @@ -348,14 +340,12 @@ public static void handleSequenceGenerator( configuration.put( GENERATOR_NAME, generatorName ); } else { - SequenceStyleGenerator.applyConfiguration( generatorConfig, idValue, configuration::put ); + SequenceStyleGenerator.applyConfiguration( generatorConfig, configuration::put ); } GeneratorBinder.createGeneratorFrom( new IdentifierGeneratorDefinition( generatorName, SequenceStyleGenerator.class.getName(), configuration ), - idMember, idValue, - entityMapping, context ); diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/relational/Namespace.java b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/Namespace.java index 5c570641078c..695e5ef3fab4 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/relational/Namespace.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/relational/Namespace.java @@ -364,7 +364,7 @@ public boolean equals(Object o) { final Name that = (Name) o; return Objects.equals( this.catalog, that.catalog ) - && Objects.equals( this.schema, that.schema ); + && Objects.equals( this.schema, that.schema ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java b/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java index edfe31dadd7b..c68031ab0090 100644 --- a/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java +++ b/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java @@ -8,12 +8,15 @@ import org.hibernate.Incubating; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.RootClass; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.Type; +import static org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl.fromExplicit; + /** * Access to information useful during {@linkplain Generator} creation and initialization. * @@ -65,4 +68,9 @@ public interface GeneratorCreationContext { default Type getType() { return getProperty().getType(); } + + default SqlStringGenerationContext getSqlStringGenerationContext() { + final Database database = getDatabase(); + return fromExplicit( database.getJdbcEnvironment(), database, getDefaultCatalog(), getDefaultSchema() ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java index b257cc7cf298..eaa2b76d0652 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java @@ -31,7 +31,6 @@ import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.id.SequenceMismatchStrategy; import org.hibernate.internal.CoreMessageLogger; -import org.hibernate.mapping.SimpleValue; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.schema.Action; import org.hibernate.tool.schema.extract.spi.SequenceInformation; @@ -206,7 +205,7 @@ public void configure(GeneratorCreationContext creationContext, Properties param this.identifierType = creationContext.getType(); - final QualifiedName sequenceName = determineSequenceName( parameters, dialect, jdbcEnvironment, serviceRegistry ); + final QualifiedName sequenceName = determineSequenceName( parameters, jdbcEnvironment, serviceRegistry ); final int initialValue = determineInitialValue( parameters ); int incrementSize = determineIncrementSize( parameters ); final OptimizerDescriptor optimizationStrategy = determineOptimizationStrategy( parameters, incrementSize ); @@ -329,15 +328,13 @@ public void initialize(SqlStringGenerationContext context) { *

* Called during {@linkplain #configure configuration}. * - * @param params The params supplied in the generator config (plus some standard useful extras). - * @param dialect The dialect in effect + * @param params The params supplied in the generator config (plus some standard useful extras). * @param jdbcEnv The JdbcEnvironment * @return The sequence name */ @SuppressWarnings("UnusedParameters") protected QualifiedName determineSequenceName( Properties params, - Dialect dialect, JdbcEnvironment jdbcEnv, ServiceRegistry serviceRegistry) { final IdentifierHelper identifierHelper = jdbcEnv.getIdentifierHelper(); @@ -587,7 +584,7 @@ private static boolean isDefaultSchema(JdbcEnvironment jdbcEnvironment, Identifi && ( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) ); } - public static void applyConfiguration(SequenceGenerator generatorConfig, SimpleValue idValue, BiConsumer configCollector) { + public static void applyConfiguration(SequenceGenerator generatorConfig, BiConsumer configCollector) { if ( !generatorConfig.sequenceName().isEmpty() ) { configCollector.accept( SEQUENCE_PARAM, generatorConfig.sequenceName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java index 7989bc50cfba..8d775c5c9666 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java @@ -45,7 +45,6 @@ import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.mapping.Column; import org.hibernate.mapping.PrimaryKey; -import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Table; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.BasicTypeRegistry; @@ -728,14 +727,6 @@ public void initialize(SqlStringGenerationContext context) { public static void applyConfiguration( jakarta.persistence.TableGenerator generatorConfig, - SimpleValue idValue, - Map configuration) { - applyConfiguration( generatorConfig, idValue, configuration::put ); - } - - public static void applyConfiguration( - jakarta.persistence.TableGenerator generatorConfig, - SimpleValue idValue, BiConsumer configurationCollector) { configurationCollector.accept( CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 78798a290540..48520e0b10b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -73,10 +73,9 @@ import org.hibernate.jpa.internal.ExceptionMapperLegacyJpaImpl; import org.hibernate.jpa.internal.PersistenceUnitUtilImpl; import org.hibernate.mapping.Collection; -import org.hibernate.mapping.KeyValue; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.RootClass; -import org.hibernate.mapping.SimpleValue; import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl; @@ -264,7 +263,7 @@ public SessionFactoryImpl( try { integrate( bootMetamodel, bootstrapContext, integratorObserver ); - identifierGenerators = createGenerators( jdbcServices, sqlStringGenerationContext, bootMetamodel ); + identifierGenerators = createGenerators( jdbcServices, bootMetamodel, options ); bootMetamodel.orderColumns( false ); bootMetamodel.validate(); @@ -415,26 +414,34 @@ public ServiceRegistry getServiceRegistry() { }; } - private static Map createGenerators( - JdbcServices jdbcServices, - SqlStringGenerationContext sqlStringGenerationContext, - MetadataImplementor bootMetamodel) { + private Map createGenerators( + JdbcServices jdbcServices, MetadataImplementor metamodel, SessionFactoryOptions options) { final Dialect dialect = jdbcServices.getJdbcEnvironment().getDialect(); final Map generators = new HashMap<>(); - for ( PersistentClass model : bootMetamodel.getEntityBindings() ) { - if ( !model.isInherited() ) { - final KeyValue id = model.getIdentifier(); + for ( PersistentClass model : metamodel.getEntityBindings() ) { + if ( model instanceof RootClass rootClass ) { final Generator generator = - id.createGenerator( dialect, (RootClass) model, model.getIdentifierProperty() ); + model.getIdentifier() + // returns the cached Generator if it was already created + .createGenerator( dialect, rootClass, model.getIdentifierProperty(), + new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + return options.getDefaultCatalog(); + } + + @Override + public String getDefaultSchema() { + return options.getDefaultSchema(); + } + } ); + // the cached generator might have been created from + // InFlightMetadataCollectorImpl.handleIdentifierValueBinding, + // in which case it did not have access to the property-configured + // default catalog and schema, so re-render SQL here if ( generator instanceof Configurable configurable ) { configurable.initialize( sqlStringGenerationContext ); } - //TODO: this isn't a great place to do this - if ( generator.allowAssignedIdentifiers() - && id instanceof SimpleValue simpleValue - && simpleValue.getNullValue() == null ) { - simpleValue.setNullValue( "undefined" ); - } generators.put( model.getEntityName(), generator ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java index 494f44f7e07e..7d3cc3f94c9a 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java @@ -651,17 +651,17 @@ public String toString() { } @Override - public Generator createGenerator(Dialect dialect, RootClass rootClass, Property property) { + public Generator createGenerator(Dialect dialect, RootClass rootClass, Property property, GeneratorSettings defaults) { if ( builtIdentifierGenerator == null ) { builtIdentifierGenerator = getCustomIdGeneratorCreator().isAssigned() - ? buildIdentifierGenerator( dialect, rootClass ) - : super.createGenerator( dialect, rootClass, property ); + ? buildIdentifierGenerator( dialect, rootClass, defaults ) + : super.createGenerator( dialect, rootClass, property, defaults ); } return builtIdentifierGenerator; } - private Generator buildIdentifierGenerator(Dialect dialect, RootClass rootClass) { + private Generator buildIdentifierGenerator(Dialect dialect, RootClass rootClass, GeneratorSettings defaults) { final CompositeNestedGeneratedValueGenerator generator = new CompositeNestedGeneratedValueGenerator( new StandardGenerationContextLocator( rootClass.getEntityName() ), @@ -675,7 +675,7 @@ private Generator buildIdentifierGenerator(Dialect dialect, RootClass rootClass) if ( !value.getCustomIdGeneratorCreator().isAssigned() ) { // skip any 'assigned' generators, they would have been // handled by the StandardGenerationContextLocator - if ( value.createGenerator( dialect, rootClass, property ) + if ( value.createGenerator( dialect, rootClass, property, defaults ) instanceof BeforeExecutionGenerator beforeExecutionGenerator ) { generator.addGeneratedValuePlan( new ValueGenerationPlan( beforeExecutionGenerator, diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java b/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java new file mode 100644 index 000000000000..9b96ee59f1cd --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java @@ -0,0 +1,14 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.mapping; + + +/** + * @author Gavin King + */ +public interface GeneratorSettings { + String getDefaultCatalog(); + String getDefaultSchema(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java index 4ffded8c8076..4c9801994f7f 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java @@ -27,9 +27,12 @@ public interface KeyValue extends Value { @Deprecated(since = "7.0") default Generator createGenerator(Dialect dialect, RootClass rootClass) { - return createGenerator( dialect, rootClass, null ); + return createGenerator( dialect, rootClass, null, null ); } - Generator createGenerator(Dialect dialect, RootClass rootClass, Property property); - + Generator createGenerator( + Dialect dialect, + RootClass rootClass, + Property property, + GeneratorSettings defaults); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Property.java b/hibernate-core/src/main/java/org/hibernate/mapping/Property.java index d21302512d64..d31c01799cc3 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Property.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Property.java @@ -13,6 +13,7 @@ import org.hibernate.Internal; import org.hibernate.MappingException; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.spi.CascadeStyle; @@ -31,7 +32,6 @@ import org.hibernate.type.AnyType; import org.hibernate.type.CollectionType; import org.hibernate.type.ComponentType; -import org.hibernate.type.CompositeType; import org.hibernate.type.Type; import org.hibernate.type.WrapperArrayHandling; import org.hibernate.type.MappingContext; @@ -129,8 +129,7 @@ public void resetUpdateable(boolean updateable) { public void resetOptional(boolean optional) { setOptional( optional ); for ( Selectable selectable: getValue().getSelectables() ) { - if (selectable instanceof Column) { - final Column column = (Column) selectable; + if ( selectable instanceof Column column ) { column.setNullable( optional ); } } @@ -152,15 +151,15 @@ else if ( type instanceof CollectionType ) { return getCascadeStyle( cascade ); } } - - private static CascadeStyle getCompositeCascadeStyle(CompositeType compositeType, String cascade) { - if ( compositeType instanceof AnyType ) { - return getCascadeStyle( cascade ); - } - else { - return getCompositeCascadeStyle( (ComponentType) compositeType, cascade ); - } - } +// +// private static CascadeStyle getCompositeCascadeStyle(CompositeType compositeType, String cascade) { +// if ( compositeType instanceof AnyType ) { +// return getCascadeStyle( cascade ); +// } +// else { +// return getCompositeCascadeStyle( (ComponentType) compositeType, cascade ); +// } +// } private static CascadeStyle getCompositeCascadeStyle(ComponentType compositeType, String cascade) { final int length = compositeType.getSubtypes().length; @@ -543,5 +542,10 @@ public RootClass getRootClass() { public Property getProperty() { return Property.this; } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return context.getSqlStringGenerationContext(); + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index 6c664d33079d..0b46763eab8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -376,10 +376,19 @@ public GeneratorCreator getCustomIdGeneratorCreator() { } @Override - public Generator createGenerator(Dialect dialect, RootClass rootClass, Property property) { + public Generator createGenerator( + Dialect dialect, + RootClass rootClass, + Property property, + GeneratorSettings defaults) { if ( generator == null ) { if ( customIdGeneratorCreator != null ) { - generator = customIdGeneratorCreator.createGenerator( new IdGeneratorCreationContext( rootClass, property ) ); + final IdGeneratorCreationContext context = + new IdGeneratorCreationContext( rootClass, property, defaults ); + generator = customIdGeneratorCreator.createGenerator( context ); + if ( generator.allowAssignedIdentifiers() && getNullValue() == null ) { + setNullValue( "undefined" ); + } } } return generator; @@ -903,8 +912,7 @@ public DynamicParameterizedType.ParameterType makeParameterImpl() { for ( int i = 0; i < columns.size(); i++ ) { final Selectable selectable = columns.get(i); - if ( selectable instanceof Column ) { - final Column column = (Column) selectable; + if ( selectable instanceof Column column ) { columnNames[i] = column.getName(); columnLengths[i] = column.getLength(); } @@ -1029,10 +1037,12 @@ public Long[] getColumnLengths() { private class IdGeneratorCreationContext implements GeneratorCreationContext { private final RootClass rootClass; private final Property property; + private final GeneratorSettings defaults; - public IdGeneratorCreationContext(RootClass rootClass, Property property) { + public IdGeneratorCreationContext(RootClass rootClass, Property property, GeneratorSettings defaults) { this.rootClass = rootClass; this.property = property; + this.defaults = defaults; } @Override @@ -1047,12 +1057,12 @@ public ServiceRegistry getServiceRegistry() { @Override public String getDefaultCatalog() { - return buildingContext.getEffectiveDefaults().getDefaultCatalogName(); + return defaults.getDefaultCatalog(); } @Override public String getDefaultSchema() { - return buildingContext.getEffectiveDefaults().getDefaultSchemaName(); + return defaults.getDefaultSchema(); } @Override @@ -1075,7 +1085,7 @@ public Type getType() { return SimpleValue.this.getType(); } - // we could add these if it helps integrate old infrastructure + // we could add this if it helps integrate old infrastructure // @Override // public Properties getParameters() { // final Value value = getProperty().getValue(); @@ -1086,10 +1096,5 @@ public Type getType() { // return collectParameters( (SimpleValue) value, dialect, defaultCatalog, defaultSchema, rootClass ); // } // -// @Override -// public SqlStringGenerationContext getSqlStringGenerationContext() { -// final Database database = getDatabase(); -// return fromExplicit( database.getJdbcEnvironment(), database, defaultCatalog, defaultSchema ); -// } } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 157828f5fd21..8e08d7e5b953 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -47,7 +47,6 @@ import org.hibernate.engine.spi.SubselectFetch; import org.hibernate.generator.BeforeExecutionGenerator; import org.hibernate.generator.Generator; -import org.hibernate.id.Configurable; import org.hibernate.id.IdentifierGenerator; import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.internal.FilterHelper; @@ -65,6 +64,7 @@ import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.PersistentClass; @@ -594,13 +594,23 @@ else if ( indexedCollection instanceof org.hibernate.mapping.Map } private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) { - final Generator generator = collection.getIdentifier().createGenerator( context.getDialect(), null, null ); + final Generator generator = + collection.getIdentifier() + .createGenerator( context.getDialect(), null, null, + new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + return context.getSessionFactoryOptions().getDefaultCatalog(); + } + + @Override + public String getDefaultSchema() { + return context.getSessionFactoryOptions().getDefaultCatalog(); + } + } ); if ( generator.generatedOnExecution() ) { throw new MappingException("must be an BeforeExecutionGenerator"); //TODO fix message } - if ( generator instanceof Configurable ) { - ( (Configurable) generator ).initialize( context.getSqlStringGenerationContext() ); - } return (BeforeExecutionGenerator) generator; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java index 6e2335d1e097..9f7b5d6d9103 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java @@ -91,7 +91,8 @@ private void withGenerator(Class entityClass, boolean strictlyGlobal, Consume final Generator generator = entityBinding.getIdentifier().createGenerator( metadata.getDatabase().getDialect(), entityBinding, - entityBinding.getIdentifierProperty() + entityBinding.getIdentifierProperty(), + null ); checks.accept( generator ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/idgen/enhanced/auto/AutoGenerationTypeTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/idgen/enhanced/auto/AutoGenerationTypeTests.java index 761080ab3df9..263ca32b469f 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/idgen/enhanced/auto/AutoGenerationTypeTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/idgen/enhanced/auto/AutoGenerationTypeTests.java @@ -134,7 +134,7 @@ public void testUuid() { final Property identifierProperty = entityBinding.getRootClass().getIdentifierProperty(); final KeyValue idMapping = entityBinding.getRootClass().getIdentifier(); Dialect dialect = new H2Dialect(); - final Generator generator = idMapping.createGenerator( dialect, entityBinding.getRootClass(), identifierProperty ); + final Generator generator = idMapping.createGenerator( dialect, entityBinding.getRootClass(), identifierProperty, null ); MatcherAssert.assertThat( generator, instanceOf( UuidGenerator.class ) ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java index 4602e2267df2..7f36bed33e62 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/FunctionTests.java @@ -69,7 +69,6 @@ import static org.hibernate.testing.orm.domain.gambit.EntityOfBasics.Gender.FEMALE; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.assertThrows; From d30178f5b526cb939267add3310c983b6887673a Mon Sep 17 00:00:00 2001 From: Gavin King Date: Thu, 19 Sep 2024 14:13:43 +0200 Subject: [PATCH 2/4] don't cache the Generator in the SimpleValue that way we don't need to re-call initialize() on the cached instance also handle canonicalization of generators via RuntimeModelCreationContext instead of via deprecated method or SessionFactoryImplementor --- .../InFlightMetadataCollectorImpl.java | 1 - .../internal/SessionFactoryImpl.java | 46 +++---------------- .../java/org/hibernate/mapping/Component.java | 12 ++--- .../java/org/hibernate/mapping/KeyValue.java | 12 ++++- .../org/hibernate/mapping/SimpleValue.java | 21 ++++----- .../spi/RuntimeModelCreationContext.java | 3 ++ .../entity/AbstractEntityPersister.java | 14 ++---- .../tuple/entity/EntityMetamodel.java | 39 ++++++++++++++-- ...poraryTableMutationStrategyNoDropTest.java | 7 +++ .../id/generators/UnnamedGeneratorTests.java | 13 +++++- .../id/PooledHiLoSequenceIdentifierTest.java | 2 +- .../id/custom/CustomSequenceGenerator.java | 37 ++++++++------- 12 files changed, 114 insertions(+), 93 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 53abd33d07ed..96912893affc 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -2204,7 +2204,6 @@ private void processExportableProducers() { private void handleIdentifierValueBinding( KeyValue identifierValueBinding, Dialect dialect, RootClass entityBinding, Property identifierProperty) { try { - // this call typically caches the new Generator in the instance of KeyValue identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty, new GeneratorSettings() { @Override diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 48520e0b10b4..830875bbba25 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -67,13 +67,11 @@ import org.hibernate.event.spi.EventEngine; import org.hibernate.generator.Generator; import org.hibernate.graph.spi.RootGraphImplementor; -import org.hibernate.id.Configurable; import org.hibernate.integrator.spi.Integrator; import org.hibernate.integrator.spi.IntegratorService; import org.hibernate.jpa.internal.ExceptionMapperLegacyJpaImpl; import org.hibernate.jpa.internal.PersistenceUnitUtilImpl; import org.hibernate.mapping.Collection; -import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.RootClass; import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl; @@ -185,8 +183,6 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im private final transient CurrentSessionContext currentSessionContext; - // todo : move to MetamodelImpl - private final transient Map identifierGenerators; private final transient Map filters; private final transient java.util.Collection autoEnabledFilters = new HashSet<>(); private final transient Map fetchProfiles; @@ -263,7 +259,6 @@ public SessionFactoryImpl( try { integrate( bootMetamodel, bootstrapContext, integratorObserver ); - identifierGenerators = createGenerators( jdbcServices, bootMetamodel, options ); bootMetamodel.orderColumns( false ); bootMetamodel.validate(); @@ -346,6 +341,8 @@ private RuntimeModelCreationContext runtimeModelCreationContext( TypeConfiguration typeConfiguration, SessionFactoryOptions options) { return new RuntimeModelCreationContext() { + final Map generators = new HashMap<>(); + @Override public BootstrapContext getBootstrapContext() { return bootstrapContext; @@ -411,41 +408,12 @@ public SqlStringGenerationContext getSqlStringGenerationContext() { public ServiceRegistry getServiceRegistry() { return serviceRegistry; } - }; - } - private Map createGenerators( - JdbcServices jdbcServices, MetadataImplementor metamodel, SessionFactoryOptions options) { - final Dialect dialect = jdbcServices.getJdbcEnvironment().getDialect(); - final Map generators = new HashMap<>(); - for ( PersistentClass model : metamodel.getEntityBindings() ) { - if ( model instanceof RootClass rootClass ) { - final Generator generator = - model.getIdentifier() - // returns the cached Generator if it was already created - .createGenerator( dialect, rootClass, model.getIdentifierProperty(), - new GeneratorSettings() { - @Override - public String getDefaultCatalog() { - return options.getDefaultCatalog(); - } - - @Override - public String getDefaultSchema() { - return options.getDefaultSchema(); - } - } ); - // the cached generator might have been created from - // InFlightMetadataCollectorImpl.handleIdentifierValueBinding, - // in which case it did not have access to the property-configured - // default catalog and schema, so re-render SQL here - if ( generator instanceof Configurable configurable ) { - configurable.initialize( sqlStringGenerationContext ); - } - generators.put( model.getEntityName(), generator ); + @Override + public Map getGenerators() { + return generators; } - } - return generators; + }; } private static SqlStringGenerationContext createSqlStringGenerationContext( @@ -1086,7 +1054,7 @@ public Set getDefinedFetchProfileNames() { @Override @Deprecated public Generator getGenerator(String rootEntityName) { - return identifierGenerators.get( rootEntityName ); + return null; } private boolean canAccessTransactionManager() { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java index 7d3cc3f94c9a..4086c65f1663 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java @@ -106,8 +106,6 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable private transient Class componentClass; private transient Boolean simpleRecord; - private transient Generator builtIdentifierGenerator; - public Component(MetadataBuildingContext metadata, PersistentClass owner) throws MappingException { this( metadata, owner.getTable(), owner ); } @@ -652,13 +650,9 @@ public String toString() { @Override public Generator createGenerator(Dialect dialect, RootClass rootClass, Property property, GeneratorSettings defaults) { - if ( builtIdentifierGenerator == null ) { - builtIdentifierGenerator = - getCustomIdGeneratorCreator().isAssigned() - ? buildIdentifierGenerator( dialect, rootClass, defaults ) - : super.createGenerator( dialect, rootClass, property, defaults ); - } - return builtIdentifierGenerator; + return getCustomIdGeneratorCreator().isAssigned() + ? buildIdentifierGenerator( dialect, rootClass, defaults ) + : super.createGenerator( dialect, rootClass, property, defaults ); } private Generator buildIdentifierGenerator(Dialect dialect, RootClass rootClass, GeneratorSettings defaults) { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java index 4c9801994f7f..7650f273970f 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java @@ -27,7 +27,17 @@ public interface KeyValue extends Value { @Deprecated(since = "7.0") default Generator createGenerator(Dialect dialect, RootClass rootClass) { - return createGenerator( dialect, rootClass, null, null ); + return createGenerator( dialect, rootClass, null, new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + return null; + } + + @Override + public String getDefaultSchema() { + return null; + } + } ); } Generator createGenerator( diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index 0b46763eab8f..b46af15ff53b 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -103,7 +103,6 @@ public abstract class SimpleValue implements KeyValue { private Type type; private GeneratorCreator customIdGeneratorCreator = ASSIGNED_IDENTIFIER_GENERATOR_CREATOR; - private Generator generator; public SimpleValue(MetadataBuildingContext buildingContext) { this.buildingContext = buildingContext; @@ -137,7 +136,6 @@ protected SimpleValue(SimpleValue original) { this.attributeConverterDescriptor = original.attributeConverterDescriptor; this.type = original.type; this.customIdGeneratorCreator = original.customIdGeneratorCreator; - this.generator = original.generator; } @Override @@ -381,17 +379,18 @@ public Generator createGenerator( RootClass rootClass, Property property, GeneratorSettings defaults) { - if ( generator == null ) { - if ( customIdGeneratorCreator != null ) { - final IdGeneratorCreationContext context = - new IdGeneratorCreationContext( rootClass, property, defaults ); - generator = customIdGeneratorCreator.createGenerator( context ); - if ( generator.allowAssignedIdentifiers() && getNullValue() == null ) { - setNullValue( "undefined" ); - } + if ( customIdGeneratorCreator != null ) { + final IdGeneratorCreationContext context = + new IdGeneratorCreationContext( rootClass, property, defaults ); + final Generator generator = customIdGeneratorCreator.createGenerator( context ); + if ( generator.allowAssignedIdentifiers() && getNullValue() == null ) { + setNullValue( "undefined" ); } + return generator; + } + else { + return null; } - return generator; } @Internal diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java index 63f43908ab63..9968b2eb643b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java @@ -12,6 +12,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.generator.Generator; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; @@ -58,4 +59,6 @@ default MetadataImplementor getMetadata() { SqlStringGenerationContext getSqlStringGenerationContext(); ServiceRegistry getServiceRegistry(); + + Map getGenerators(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 612ec60d0c0b..d67623531712 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -909,15 +909,11 @@ private static CacheLayout queryCacheLayout(CacheLayout entityQueryCacheLayout, } private boolean shouldUseShallowCacheLayout(CacheLayout entityQueryCacheLayout, SessionFactoryOptions options) { - switch ( queryCacheLayout( entityQueryCacheLayout, options ) ) { - case FULL: - return false; - case AUTO: - return canUseReferenceCacheEntries() - || canReadFromCache(); - default: - return true; - } + return switch ( queryCacheLayout( entityQueryCacheLayout, options ) ) { + case FULL -> false; + case AUTO -> canUseReferenceCacheEntries() || canReadFromCache(); + default -> true; + }; } private static boolean shouldStoreDiscriminatorInShallowQueryCacheLayout( diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 317b22f2bcdc..e2d878e68d80 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -18,6 +18,7 @@ import org.hibernate.MappingException; import org.hibernate.annotations.NotFoundAction; import org.hibernate.boot.spi.MetadataImplementor; +import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataPojoImpl; @@ -34,6 +35,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Component; import org.hibernate.mapping.GeneratorCreator; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -160,10 +162,8 @@ public EntityMetamodel( subclassId = persistentClass.getSubclassId(); - identifierAttribute = PropertyFactory.buildIdentifierAttribute( - persistentClass, - sessionFactory.getGenerator( rootName ) - ); + final Generator idgenerator = buildIdGenerator( persistentClass, creationContext ); + identifierAttribute = PropertyFactory.buildIdentifierAttribute( persistentClass, idgenerator ); versioned = persistentClass.isVersioned(); @@ -472,6 +472,37 @@ && isAbstractClass( persistentClass.getMappedClass() ) ) { // entityNameByInheritanceClassMap = toSmallMap( entityNameByInheritanceClassMapLocal ); } + private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModelCreationContext creationContext) { + final Generator existing = creationContext.getGenerators().get( rootName ); + if ( existing != null ) { + return existing; + } + else { + final Generator idgenerator = + persistentClass.getIdentifier() + // returns the cached Generator if it was already created + .createGenerator( + creationContext.getDialect(), + persistentClass.getRootClass(), + persistentClass.getIdentifierProperty(), + new GeneratorSettings() { + SessionFactoryOptions options() { + return creationContext.getSessionFactory().getSessionFactoryOptions(); + } + @Override + public String getDefaultCatalog() { + return options().getDefaultCatalog(); + } + @Override + public String getDefaultSchema() { + return options().getDefaultSchema(); + } + } ); + creationContext.getGenerators().put( rootName, idgenerator ); + return idgenerator; + } + } + private void verifyNaturalIdProperty(Property property) { final Value value = property.getValue(); if ( value instanceof ManyToOne toOne ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java index 0e56fba4d9e6..aed5710939e2 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java @@ -19,6 +19,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.generator.Generator; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.query.sqm.function.SqmFunctionRegistry; @@ -40,6 +41,7 @@ import jakarta.persistence.Inheritance; import jakarta.persistence.InheritanceType; +import static java.util.Collections.emptyMap; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; @DomainModel( @@ -165,6 +167,11 @@ public SqlStringGenerationContext getSqlStringGenerationContext() { public org.hibernate.service.ServiceRegistry getServiceRegistry() { return sessionFactory.getServiceRegistry(); } + + @Override + public Map getGenerators() { + return emptyMap(); + } } ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java index 9f7b5d6d9103..a1c486e5fa2d 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java @@ -13,6 +13,7 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; import org.hibernate.generator.Generator; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.RootClass; import org.junit.jupiter.api.Test; @@ -92,7 +93,17 @@ private void withGenerator(Class entityClass, boolean strictlyGlobal, Consume metadata.getDatabase().getDialect(), entityBinding, entityBinding.getIdentifierProperty(), - null + new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + return null; + } + + @Override + public String getDefaultSchema() { + return null; + } + } ); checks.accept( generator ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/PooledHiLoSequenceIdentifierTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/PooledHiLoSequenceIdentifierTest.java index 130e6c44b5c8..bb4cc50a4568 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/PooledHiLoSequenceIdentifierTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/PooledHiLoSequenceIdentifierTest.java @@ -108,7 +108,7 @@ private void insertNewRow(Session session) { statement = connection.prepareStatement( "INSERT INTO sequenceIdentifier VALUES (?,?)" ); statement.setObject( 1, - ((BeforeExecutionGenerator) sfi.getGenerator( SequenceIdentifier.class.getName() )) + ((BeforeExecutionGenerator) sfi.getMappingMetamodel().getEntityDescriptor( SequenceIdentifier.class).getGenerator()) .generate( si, null, null, EventType.INSERT ) ); statement.setString( 2,"name" ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/custom/CustomSequenceGenerator.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/custom/CustomSequenceGenerator.java index 7bffafefb906..e29d1cf6a291 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/id/custom/CustomSequenceGenerator.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/custom/CustomSequenceGenerator.java @@ -11,6 +11,7 @@ import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.model.relational.Namespace; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.generator.GeneratorCreationContext; @@ -24,7 +25,6 @@ public class CustomSequenceGenerator implements IdentifierGenerator { //end::identifiers-IdGeneratorType-example[] public static int generationCount = 0; - private final Identifier sequenceName; private final String sqlSelectFrag; //tag::identifiers-IdGeneratorType-example[] @@ -42,23 +42,26 @@ public CustomSequenceGenerator( final Database database = context.getDatabase(); final IdentifierHelper identifierHelper = database.getJdbcEnvironment().getIdentifierHelper(); - final org.hibernate.boot.model.relational.Sequence sequence = database.getDefaultNamespace().createSequence( - identifierHelper.toIdentifier( name ), - (physicalName) -> new org.hibernate.boot.model.relational.Sequence( - null, - database.getDefaultNamespace().getPhysicalName().getCatalog(), - database.getDefaultNamespace().getPhysicalName().getSchema(), - physicalName, - 1, - 50 - ) - ); - this.sequenceName = sequence.getName().getSequenceName(); + final Identifier identifier = identifierHelper.toIdentifier( name ); + final Namespace defaultNamespace = database.getDefaultNamespace(); + org.hibernate.boot.model.relational.Sequence sequence = defaultNamespace.locateSequence( identifier ); + if ( sequence == null ) { + sequence = defaultNamespace.createSequence( + identifier, + (physicalName) -> new org.hibernate.boot.model.relational.Sequence( + null, + defaultNamespace.getPhysicalName().getCatalog(), + defaultNamespace.getPhysicalName().getSchema(), + physicalName, + 1, + 50 + ) + ); + } - this.sqlSelectFrag = database - .getDialect() - .getSequenceSupport() - .getSequenceNextValString( sequenceName.render( database.getDialect() ) ); + this.sqlSelectFrag = + database.getDialect().getSequenceSupport() + .getSequenceNextValString( sequence.getName().getSequenceName().render( database.getDialect() ) ); //tag::identifiers-IdGeneratorType-example[] } From df3d7b053e81df582102cdc85595acf2add6e985 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Thu, 19 Sep 2024 20:42:30 +0200 Subject: [PATCH 3/4] more fallout from new Generator instantiation lifecycle --- .../InFlightMetadataCollectorImpl.java | 55 +++-- .../boot/spi/SessionFactoryOptions.java | 4 + .../generator/GeneratorCreationContext.java | 7 +- .../internal/SessionFactoryImpl.java | 211 +++++++++--------- .../hibernate/mapping/GeneratorSettings.java | 19 ++ .../java/org/hibernate/mapping/KeyValue.java | 26 +-- .../org/hibernate/mapping/SimpleValue.java | 32 ++- .../spi/RuntimeModelCreationContext.java | 3 + .../AbstractCollectionPersister.java | 14 +- .../tuple/entity/EntityMetamodel.java | 17 +- ...poraryTableMutationStrategyNoDropTest.java | 174 +++++++++------ .../id/generators/UnnamedGeneratorTests.java | 7 + 12 files changed, 323 insertions(+), 246 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 96912893affc..f39b55bf76ff 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -56,6 +56,7 @@ import org.hibernate.boot.model.relational.Database; import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.relational.QualifiedTableName; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.boot.model.source.internal.ImplicitColumnNamingSecondPass; import org.hibernate.boot.model.source.spi.LocalMetadataBuildingContext; import org.hibernate.boot.models.categorize.internal.ClassLoaderServiceLoading; @@ -78,6 +79,8 @@ import org.hibernate.boot.spi.SecondPass; import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.config.spi.ConfigurationService; +import org.hibernate.engine.config.spi.StandardConverters; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.CoreLogging; @@ -120,6 +123,9 @@ import jakarta.persistence.MapsId; import static org.hibernate.boot.model.naming.Identifier.toIdentifier; +import static org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl.fromExplicit; +import static org.hibernate.cfg.MappingSettings.DEFAULT_CATALOG; +import static org.hibernate.cfg.MappingSettings.DEFAULT_SCHEMA; import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; /** @@ -132,7 +138,8 @@ * * @author Steve Ebersole */ -public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector, ConverterRegistry { +public class InFlightMetadataCollectorImpl + implements InFlightMetadataCollector, ConverterRegistry, GeneratorSettings { private static final CoreMessageLogger log = CoreLogging.messageLogger( InFlightMetadataCollectorImpl.class ); private final BootstrapContext bootstrapContext; @@ -170,6 +177,8 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector, private Map sqlFunctionMap; + final ConfigurationService configurationService; + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // All the annotation-processing-specific state :( private final Set defaultIdentifierGeneratorNames = new HashSet<>(); @@ -210,16 +219,12 @@ public InFlightMetadataCollectorImpl( } bootstrapContext.getAuxiliaryDatabaseObjectList().forEach( getDatabase()::addAuxiliaryDatabaseObject ); + + configurationService = bootstrapContext.getServiceRegistry().requireService(ConfigurationService.class); } - public InFlightMetadataCollectorImpl( - BootstrapContext bootstrapContext, - MetadataBuildingOptions options) { - this( - bootstrapContext, - createModelBuildingContext( bootstrapContext ), - options - ); + public InFlightMetadataCollectorImpl(BootstrapContext bootstrapContext, MetadataBuildingOptions options) { + this( bootstrapContext, createModelBuildingContext( bootstrapContext ), options ); } private static SourceModelBuildingContext createModelBuildingContext(BootstrapContext bootstrapContext) { @@ -2204,20 +2209,7 @@ private void processExportableProducers() { private void handleIdentifierValueBinding( KeyValue identifierValueBinding, Dialect dialect, RootClass entityBinding, Property identifierProperty) { try { - identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty, - new GeneratorSettings() { - @Override - public String getDefaultCatalog() { - //TODO: does not have access to property-configured default - return persistenceUnitMetadata.getDefaultCatalog(); - } - - @Override - public String getDefaultSchema() { - //TODO: does not have access to property-configured default - return persistenceUnitMetadata.getDefaultSchema(); - } - } ); + identifierValueBinding.createGenerator( dialect, entityBinding, identifierProperty, this ); } catch (MappingException e) { // ignore this for now. The reasoning being "non-reflective" binding as needed @@ -2227,4 +2219,21 @@ public String getDefaultSchema() { log.debugf( "Ignoring exception thrown when trying to build IdentifierGenerator as part of Metadata building", e ); } } + + @Override + public String getDefaultCatalog() { + final String defaultCatalog = configurationService.getSetting( DEFAULT_CATALOG, StandardConverters.STRING ); + return defaultCatalog == null ? persistenceUnitMetadata.getDefaultCatalog() : defaultCatalog; + } + + @Override + public String getDefaultSchema() { + final String defaultSchema = configurationService.getSetting( DEFAULT_SCHEMA, StandardConverters.STRING ); + return defaultSchema == null ? persistenceUnitMetadata.getDefaultSchema() : defaultSchema; + } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return fromExplicit( database.getJdbcEnvironment(), database, getDefaultCatalog(), getDefaultSchema() ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java index 74f6fa97ac69..645f5ee183cf 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java @@ -244,6 +244,8 @@ default boolean getNativeJdbcParametersIgnored() { * neither explicitly nor implicitly (see the concept of implicit catalog in XML mapping). * * @return The default catalog to use. + * + * @see org.hibernate.cfg.MappingSettings#DEFAULT_CATALOG */ default String getDefaultCatalog() { return null; @@ -254,6 +256,8 @@ default String getDefaultCatalog() { * neither explicitly nor implicitly (see the concept of implicit schema in XML mapping). * * @return The default schema to use. + * + * @see org.hibernate.cfg.MappingSettings#DEFAULT_SCHEMA */ default String getDefaultSchema() { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java b/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java index c68031ab0090..f209f17f0fcf 100644 --- a/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java +++ b/hibernate-core/src/main/java/org/hibernate/generator/GeneratorCreationContext.java @@ -28,7 +28,9 @@ @Incubating public interface GeneratorCreationContext { /** - * View of the relational database objects (tables, sequences, ...) and namespaces (catalogs and schemas). + * View of the relational database objects (tables, sequences, etc.) + * and namespaces (catalogs and schemas). Generators may add new + * tables or sequences to the returned {@link Database}. */ Database getDatabase(); @@ -69,6 +71,9 @@ default Type getType() { return getProperty().getType(); } + /** + * The {@link SqlStringGenerationContext} to use when generating SQL. + */ default SqlStringGenerationContext getSqlStringGenerationContext() { final Database database = getDatabase(); return fromExplicit( database.getJdbcEnvironment(), database, getDefaultCatalog(), getDefaultSchema() ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 830875bbba25..1a669eb9ecc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -72,6 +72,7 @@ import org.hibernate.jpa.internal.ExceptionMapperLegacyJpaImpl; import org.hibernate.jpa.internal.PersistenceUnitUtilImpl; import org.hibernate.mapping.Collection; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.RootClass; import org.hibernate.metamodel.internal.RuntimeMetamodelsImpl; @@ -277,16 +278,16 @@ public SessionFactoryImpl( // create runtime metamodels (mapping and JPA) final RuntimeMetamodelsImpl runtimeMetamodelsImpl = new RuntimeMetamodelsImpl(); runtimeMetamodels = runtimeMetamodelsImpl; - final MappingMetamodelImpl mappingMetamodelImpl = - new MappingMetamodelImpl( typeConfiguration, serviceRegistry ); + final MappingMetamodelImpl mappingMetamodelImpl = new MappingMetamodelImpl( typeConfiguration, serviceRegistry ); runtimeMetamodelsImpl.setMappingMetamodel( mappingMetamodelImpl ); fastSessionServices = new FastSessionServices( this ); - initializeMappingModel( mappingMetamodelImpl, bootstrapContext, bootMetamodel, options ); + mappingMetamodelImpl.finishInitialization( + new ModelCreationContext( bootstrapContext, bootMetamodel, mappingMetamodelImpl, typeConfiguration ) ); runtimeMetamodelsImpl.setJpaMetamodel( mappingMetamodelImpl.getJpaMetamodel() ); // this needs to happen after the mapping metamodel is // completely built, since we need to use the persisters - fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodels ); + fetchProfiles = getFetchProfiles( bootMetamodel, runtimeMetamodelsImpl); defaultSessionOpenOptions = createDefaultSessionOpenOptionsIfPossible(); temporarySessionOpenOptions = defaultSessionOpenOptions == null ? null : buildTemporarySessionOpenOptions(); @@ -320,102 +321,6 @@ public SessionFactoryImpl( LOG.debug( "Instantiated SessionFactory" ); } - private void initializeMappingModel( - MappingMetamodelImpl mappingMetamodelImpl, - BootstrapContext bootstrapContext, - MetadataImplementor bootMetamodel, - SessionFactoryOptions options) { - mappingMetamodelImpl.finishInitialization( runtimeModelCreationContext( - bootstrapContext, - bootMetamodel, - mappingMetamodelImpl, - mappingMetamodelImpl.getTypeConfiguration(), - options - ) ); - } - - private RuntimeModelCreationContext runtimeModelCreationContext( - BootstrapContext bootstrapContext, - MetadataImplementor bootMetamodel, - MappingMetamodelImplementor mappingMetamodel, - TypeConfiguration typeConfiguration, - SessionFactoryOptions options) { - return new RuntimeModelCreationContext() { - final Map generators = new HashMap<>(); - - @Override - public BootstrapContext getBootstrapContext() { - return bootstrapContext; - } - - @Override - public SessionFactoryImplementor getSessionFactory() { - // this is bad, we're not yet fully-initialized - return SessionFactoryImpl.this; - } - - @Override - public MetadataImplementor getBootModel() { - return bootMetamodel; - } - - @Override - public MappingMetamodelImplementor getDomainModel() { - return mappingMetamodel; - } - - @Override - public CacheImplementor getCache() { - return cacheAccess; - } - - @Override - public Map getSettings() { - return settings; - } - - @Override - public Dialect getDialect() { - return jdbcServices.getDialect(); - } - - @Override - public SqmFunctionRegistry getFunctionRegistry() { - return queryEngine.getSqmFunctionRegistry(); - } - - @Override - public TypeConfiguration getTypeConfiguration() { - return typeConfiguration; - } - - @Override - public SessionFactoryOptions getSessionFactoryOptions() { - return options; - } - - @Override - public JdbcServices getJdbcServices() { - return jdbcServices; - } - - @Override - public SqlStringGenerationContext getSqlStringGenerationContext() { - return sqlStringGenerationContext; - } - - @Override - public ServiceRegistry getServiceRegistry() { - return serviceRegistry; - } - - @Override - public Map getGenerators() { - return generators; - } - }; - } - private static SqlStringGenerationContext createSqlStringGenerationContext( MetadataImplementor bootMetamodel, SessionFactoryOptions options, @@ -1687,4 +1592,110 @@ private enum Status { CLOSING, CLOSED } + + private class ModelCreationContext implements RuntimeModelCreationContext, GeneratorSettings { + final Map generators; + private final BootstrapContext bootstrapContext; + private final MetadataImplementor bootMetamodel; + private final MappingMetamodelImplementor mappingMetamodel; + private final TypeConfiguration typeConfiguration; + + private ModelCreationContext( + BootstrapContext bootstrapContext, + MetadataImplementor bootMetamodel, + MappingMetamodelImplementor mappingMetamodel, + TypeConfiguration typeConfiguration) { + this.bootstrapContext = bootstrapContext; + this.bootMetamodel = bootMetamodel; + this.mappingMetamodel = mappingMetamodel; + this.typeConfiguration = typeConfiguration; + generators = new HashMap<>(); + } + + @Override + public BootstrapContext getBootstrapContext() { + return bootstrapContext; + } + + @Override + public SessionFactoryImplementor getSessionFactory() { + // this is bad, we're not yet fully-initialized + return SessionFactoryImpl.this; + } + + @Override + public MetadataImplementor getBootModel() { + return bootMetamodel; + } + + @Override + public MappingMetamodelImplementor getDomainModel() { + return mappingMetamodel; + } + + @Override + public CacheImplementor getCache() { + return cacheAccess; + } + + @Override + public Map getSettings() { + return settings; + } + + @Override + public Dialect getDialect() { + return jdbcServices.getDialect(); + } + + @Override + public SqmFunctionRegistry getFunctionRegistry() { + return queryEngine.getSqmFunctionRegistry(); + } + + @Override + public TypeConfiguration getTypeConfiguration() { + return typeConfiguration; + } + + @Override + public SessionFactoryOptions getSessionFactoryOptions() { + return sessionFactoryOptions; + } + + @Override + public JdbcServices getJdbcServices() { + return jdbcServices; + } + + @Override + public ServiceRegistry getServiceRegistry() { + return serviceRegistry; + } + + @Override + public Map getGenerators() { + return generators; + } + + @Override + public GeneratorSettings getGeneratorSettings() { + return this; + } + + @Override + public String getDefaultCatalog() { + return sessionFactoryOptions.getDefaultCatalog(); + } + + @Override + public String getDefaultSchema() { + return sessionFactoryOptions.getDefaultSchema(); + } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return sqlStringGenerationContext; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java b/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java index 9b96ee59f1cd..c5cf5ad7fae6 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/GeneratorSettings.java @@ -5,10 +5,29 @@ package org.hibernate.mapping; +import org.hibernate.Incubating; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; +import org.hibernate.dialect.Dialect; + /** + * Exposes the default catalog and schema to the + * {@linkplain KeyValue#createGenerator(Dialect, RootClass, Property, GeneratorSettings) + * generator creation process}. The defaults specified here are ultimately + * passed to the {@linkplain org.hibernate.generator.Generator generator} + * itself via the {@link org.hibernate.generator.GeneratorCreationContext}. + * + * @see org.hibernate.cfg.MappingSettings#DEFAULT_CATALOG + * @see org.hibernate.cfg.MappingSettings#DEFAULT_SCHEMA + * @see org.hibernate.boot.spi.SessionFactoryOptions#getDefaultCatalog() + * @see org.hibernate.boot.spi.SessionFactoryOptions#getDefaultSchema() + * + * @since 7 + * * @author Gavin King */ +@Incubating public interface GeneratorSettings { String getDefaultCatalog(); String getDefaultSchema(); + SqlStringGenerationContext getSqlStringGenerationContext(); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java index 7650f273970f..4118269d9e04 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java @@ -4,6 +4,7 @@ */ package org.hibernate.mapping; +import org.hibernate.Incubating; import org.hibernate.dialect.Dialect; import org.hibernate.generator.Generator; @@ -25,24 +26,9 @@ public interface KeyValue extends Value { boolean isUpdateable(); - @Deprecated(since = "7.0") - default Generator createGenerator(Dialect dialect, RootClass rootClass) { - return createGenerator( dialect, rootClass, null, new GeneratorSettings() { - @Override - public String getDefaultCatalog() { - return null; - } - - @Override - public String getDefaultSchema() { - return null; - } - } ); - } - - Generator createGenerator( - Dialect dialect, - RootClass rootClass, - Property property, - GeneratorSettings defaults); + @Deprecated(since = "7.0", forRemoval = true) + Generator createGenerator(Dialect dialect, RootClass rootClass); + + @Incubating + Generator createGenerator(Dialect dialect, RootClass rootClass, Property property, GeneratorSettings defaults); } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index b46af15ff53b..8474cdeebbf1 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -26,6 +26,7 @@ import org.hibernate.boot.model.convert.spi.JpaAttributeConverterCreationContext; import org.hibernate.boot.model.internal.AnnotatedJoinColumns; import org.hibernate.boot.model.relational.Database; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.boot.spi.InFlightMetadataCollector; @@ -61,6 +62,7 @@ import static org.hibernate.boot.model.convert.spi.ConverterDescriptor.TYPE_NAME_PREFIX; import static org.hibernate.boot.model.internal.GeneratorBinder.ASSIGNED_GENERATOR_NAME; import static org.hibernate.boot.model.internal.GeneratorBinder.ASSIGNED_IDENTIFIER_GENERATOR_CREATOR; +import static org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl.fromExplicit; import static org.hibernate.internal.util.collections.ArrayHelper.toBooleanArray; /** @@ -373,6 +375,28 @@ public GeneratorCreator getCustomIdGeneratorCreator() { return customIdGeneratorCreator; } + @Deprecated(since = "7.0", forRemoval = true) + @Override @SuppressWarnings("removal") + public Generator createGenerator(Dialect dialect, RootClass rootClass) { + return createGenerator( dialect, rootClass, null, new GeneratorSettings() { + @Override + public String getDefaultCatalog() { + return null; + } + + @Override + public String getDefaultSchema() { + return null; + } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + final Database database = buildingContext.getMetadataCollector().getDatabase(); + return fromExplicit( database.getJdbcEnvironment(), database, getDefaultCatalog(), getDefaultSchema() ); + } + } ); + } + @Override public Generator createGenerator( Dialect dialect, @@ -857,8 +881,7 @@ protected void createParameterImpl() { for ( int i = 0; i < columns.size(); i++ ) { final Selectable selectable = columns.get(i); - if ( selectable instanceof Column ) { - final Column column = (Column) selectable; + if ( selectable instanceof Column column ) { columnNames[i] = column.getName(); columnLengths[i] = column.getLength(); } @@ -1054,6 +1077,11 @@ public ServiceRegistry getServiceRegistry() { return buildingContext.getBootstrapContext().getServiceRegistry(); } + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return defaults.getSqlStringGenerationContext(); + } + @Override public String getDefaultCatalog() { return defaults.getDefaultCatalog(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java index 9968b2eb643b..198d3f967469 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/RuntimeModelCreationContext.java @@ -13,6 +13,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.generator.Generator; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.query.sqm.function.SqmFunctionRegistry; import org.hibernate.service.ServiceRegistry; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; @@ -61,4 +62,6 @@ default MetadataImplementor getMetadata() { ServiceRegistry getServiceRegistry(); Map getGenerators(); + + GeneratorSettings getGeneratorSettings(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index 8e08d7e5b953..c9980b003d8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -64,7 +64,6 @@ import org.hibernate.mapping.Collection; import org.hibernate.mapping.Column; import org.hibernate.mapping.Formula; -import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.IdentifierCollection; import org.hibernate.mapping.IndexedCollection; import org.hibernate.mapping.PersistentClass; @@ -596,18 +595,7 @@ else if ( indexedCollection instanceof org.hibernate.mapping.Map private BeforeExecutionGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) { final Generator generator = collection.getIdentifier() - .createGenerator( context.getDialect(), null, null, - new GeneratorSettings() { - @Override - public String getDefaultCatalog() { - return context.getSessionFactoryOptions().getDefaultCatalog(); - } - - @Override - public String getDefaultSchema() { - return context.getSessionFactoryOptions().getDefaultCatalog(); - } - } ); + .createGenerator( context.getDialect(), null, null, context.getGeneratorSettings() ); if ( generator.generatedOnExecution() ) { throw new MappingException("must be an BeforeExecutionGenerator"); //TODO fix message } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index e2d878e68d80..178a7aa8bb45 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -18,7 +18,6 @@ import org.hibernate.MappingException; import org.hibernate.annotations.NotFoundAction; import org.hibernate.boot.spi.MetadataImplementor; -import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.bytecode.enhance.spi.interceptor.EnhancementHelper; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.bytecode.internal.BytecodeEnhancementMetadataPojoImpl; @@ -35,7 +34,6 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.mapping.Component; import org.hibernate.mapping.GeneratorCreator; -import org.hibernate.mapping.GeneratorSettings; import org.hibernate.mapping.ManyToOne; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; @@ -485,19 +483,8 @@ private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModel creationContext.getDialect(), persistentClass.getRootClass(), persistentClass.getIdentifierProperty(), - new GeneratorSettings() { - SessionFactoryOptions options() { - return creationContext.getSessionFactory().getSessionFactoryOptions(); - } - @Override - public String getDefaultCatalog() { - return options().getDefaultCatalog(); - } - @Override - public String getDefaultSchema() { - return options().getDefaultSchema(); - } - } ); + creationContext.getGeneratorSettings() + ); creationContext.getGenerators().put( rootName, idgenerator ); return idgenerator; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java index aed5710939e2..a42e002b6e6a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/LocalTemporaryTableMutationStrategyNoDropTest.java @@ -20,6 +20,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.generator.Generator; +import org.hibernate.mapping.GeneratorSettings; import org.hibernate.metamodel.spi.MappingMetamodelImplementor; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.query.sqm.function.SqmFunctionRegistry; @@ -101,78 +102,7 @@ private static TemporaryTable createTemporaryTable( session.getEntityPersister( null, new TestEntity() ), basename -> TemporaryTable.ID_TABLE_PREFIX + basename, dialect, - new RuntimeModelCreationContext() { - - @Override - public SessionFactoryImplementor getSessionFactory() { - return sessionFactory; - } - - @Override - public BootstrapContext getBootstrapContext() { - return null; - } - - @Override - public MetadataImplementor getBootModel() { - return scope.getMetadataImplementor(); - } - - @Override - public MappingMetamodelImplementor getDomainModel() { - return null; - } - - @Override - public SqmFunctionRegistry getFunctionRegistry() { - return null; - } - - @Override - public Map getSettings() { - return sessionFactory.getProperties(); - } - - @Override - public Dialect getDialect() { - return dialect; - } - - @Override - public CacheImplementor getCache() { - return null; - } - - @Override - public SessionFactoryOptions getSessionFactoryOptions() { - return sessionFactory.getSessionFactoryOptions(); - } - - @Override - public JdbcServices getJdbcServices() { - return jdbcServices; - } - - @Override - public SqlStringGenerationContext getSqlStringGenerationContext() { - return SqlStringGenerationContextImpl.fromExplicit( - jdbcServices.getJdbcEnvironment(), - scope.getMetadataImplementor().getDatabase(), - null, - null - ); - } - - @Override - public org.hibernate.service.ServiceRegistry getServiceRegistry() { - return sessionFactory.getServiceRegistry(); - } - - @Override - public Map getGenerators() { - return emptyMap(); - } - } + new ModelCreationContext( sessionFactory, scope, dialect, jdbcServices ) ); } @@ -211,4 +141,104 @@ public static class TestEntity extends ParentEntity { } + + private static class ModelCreationContext implements RuntimeModelCreationContext, GeneratorSettings { + + private final SessionFactoryImplementor sessionFactory; + private final SessionFactoryScope scope; + private final Dialect dialect; + private final JdbcServices jdbcServices; + + public ModelCreationContext(SessionFactoryImplementor sessionFactory, SessionFactoryScope scope, Dialect dialect, JdbcServices jdbcServices) { + this.sessionFactory = sessionFactory; + this.scope = scope; + this.dialect = dialect; + this.jdbcServices = jdbcServices; + } + + @Override + public SessionFactoryImplementor getSessionFactory() { + return sessionFactory; + } + + @Override + public BootstrapContext getBootstrapContext() { + return null; + } + + @Override + public MetadataImplementor getBootModel() { + return scope.getMetadataImplementor(); + } + + @Override + public MappingMetamodelImplementor getDomainModel() { + return null; + } + + @Override + public SqmFunctionRegistry getFunctionRegistry() { + return null; + } + + @Override + public Map getSettings() { + return sessionFactory.getProperties(); + } + + @Override + public Dialect getDialect() { + return dialect; + } + + @Override + public CacheImplementor getCache() { + return null; + } + + @Override + public SessionFactoryOptions getSessionFactoryOptions() { + return sessionFactory.getSessionFactoryOptions(); + } + + @Override + public JdbcServices getJdbcServices() { + return jdbcServices; + } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return SqlStringGenerationContextImpl.fromExplicit( + jdbcServices.getJdbcEnvironment(), + scope.getMetadataImplementor().getDatabase(), + null, + null + ); + } + + @Override + public org.hibernate.service.ServiceRegistry getServiceRegistry() { + return sessionFactory.getServiceRegistry(); + } + + @Override + public Map getGenerators() { + return emptyMap(); + } + + @Override + public String getDefaultCatalog() { + return null; + } + + @Override + public String getDefaultSchema() { + return null; + } + + @Override + public GeneratorSettings getGeneratorSettings() { + return this; + } + } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java index a1c486e5fa2d..40063aa30f53 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/id/generators/UnnamedGeneratorTests.java @@ -9,6 +9,8 @@ import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.model.relational.SqlStringGenerationContext; +import org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; @@ -103,6 +105,11 @@ public String getDefaultCatalog() { public String getDefaultSchema() { return null; } + + @Override + public SqlStringGenerationContext getSqlStringGenerationContext() { + return SqlStringGenerationContextImpl.forTests( metadata.getDatabase().getJdbcEnvironment() ); + } } ); From fdc93671154c68ce95ed1b07dc78e3bc1f501068 Mon Sep 17 00:00:00 2001 From: Gavin King Date: Thu, 19 Sep 2024 21:48:12 +0200 Subject: [PATCH 4/4] remove rogue ; --- hibernate-core/src/main/java/org/hibernate/id/Configurable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hibernate-core/src/main/java/org/hibernate/id/Configurable.java b/hibernate-core/src/main/java/org/hibernate/id/Configurable.java index 88acaeeab0c0..bc78f8ea3f43 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/Configurable.java +++ b/hibernate-core/src/main/java/org/hibernate/id/Configurable.java @@ -45,7 +45,7 @@ default void configure(Type type, Properties parameters, ServiceRegistry service */ default void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException { configure( creationContext.getType(), parameters, creationContext.getServiceRegistry() ); - }; + } /** * Initializes this instance, pre-generating SQL if necessary.