simplify Generator instantiation lifecycle

remove a bunch of unused parameters from methods in this package
This commit is contained in:
Gavin King 2024-09-19 10:47:34 +02:00
parent df16ea9694
commit 8ee09481b3
19 changed files with 317 additions and 337 deletions

View File

@ -54,7 +54,6 @@ import org.hibernate.boot.model.internal.SetBasicValueTypeSecondPass;
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.cfg.AvailableSettings;
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.Component;
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 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector,
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

View File

@ -94,10 +94,11 @@ public class GeneratorAnnotationHelper {
// 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 class GeneratorAnnotationHelper {
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 class GeneratorAnnotationHelper {
GenericGenerator generatorConfig,
PersistentClass entityMapping,
SimpleValue idValue,
MemberDetails idMember,
MetadataBuildingContext context) {
//generator settings
final Map<String,String> configuration = new HashMap<>();
@ -206,9 +203,7 @@ public class GeneratorAnnotationHelper {
GeneratorBinder.createGeneratorFrom(
new IdentifierGeneratorDefinition( generatorName, determineStrategyName( generatorConfig ), configuration ),
idMember,
idValue,
entityMapping,
context
);
}
@ -232,17 +227,14 @@ public class GeneratorAnnotationHelper {
TableGenerator generatorConfig,
PersistentClass entityMapping,
SimpleValue idValue,
MemberDetails idMember,
MetadataBuildingContext context) {
final Map<String,String> 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
);

View File

@ -7,7 +7,6 @@ package org.hibernate.boot.model.internal;
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.CoreMessageLogger;
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 @@ public class GeneratorBinder {
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<IdentifierGeneratorDefinition> collectIdGeneratorDefinitions(
AnnotationTarget annotatedElement,
MetadataBuildingContext context) {
final ArrayList<IdentifierGeneratorDefinition> definitions = new ArrayList<>();
visitIdGeneratorDefinitions(
annotatedElement,
definitions::add,
context
);
return definitions;
}
public static void visitIdGeneratorDefinitions(
AnnotationTarget annotatedElement,
Consumer<IdentifierGeneratorDefinition> consumer,
@ -693,7 +677,7 @@ public class GeneratorBinder {
Generator generator,
Map<String, Object> 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 class GeneratorBinder {
);
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<? extends Annotation> annotationType, Generator generator) {
@ -726,11 +716,12 @@ public class GeneratorBinder {
// 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 @@ public class GeneratorBinder {
) );
}
else {
context.getMetadataCollector().addSecondPass( new IdGeneratorResolverSecondPass(
metadataCollector.addSecondPass( new IdGeneratorResolverSecondPass(
persistentClass,
idValue,
idMember,
@ -750,7 +741,6 @@ public class GeneratorBinder {
public static void createGeneratorFrom(
IdentifierGeneratorDefinition defaultedGenerator,
MemberDetails idMember,
SimpleValue idValue,
Map<String, Object> configuration,
MetadataBuildingContext context) {
@ -766,11 +756,6 @@ public class GeneratorBinder {
if ( identifierGenerator instanceof IdentityGenerator) {
idValue.setColumnToIdentity();
}
if ( identifierGenerator instanceof ExportableProducer exportableProducer ) {
exportableProducer.registerExportables( creationContext.getDatabase() );
}
return identifierGenerator;
} );
}
@ -778,31 +763,22 @@ public class GeneratorBinder {
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<String, Object> buildConfigurationMap(
IdentifierGeneratorDefinition defaultedGenerator,
SimpleValue idValue,
PersistentClass persistentClass) {
private static Map<String, Object> buildConfigurationMap(KeyValue idValue) {
final Map<String,Object> 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 @@ public class GeneratorBinder {
final List<? extends Annotation> 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<String,String> consumer) {

View File

@ -15,6 +15,7 @@ import org.hibernate.boot.models.annotations.internal.TableGeneratorJpaAnnotatio
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 class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
entityMapping,
idValue,
idAttributeMember,
generatedValue,
buildingContext
);
case AUTO -> handleAutoStrategy(
generatorName,
entityMapping,
idValue,
idAttributeMember,
generatedValue,
buildingContext
);
}
@ -99,17 +97,18 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
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<? extends Generator> legacyNamedGenerator = GeneratorStrategies.mapLegacyNamedGenerator( generatorName, idValue );
final Class<? extends Generator> legacyNamedGenerator =
GeneratorStrategies.mapLegacyNamedGenerator( generatorName, idValue );
if ( legacyNamedGenerator != null ) {
//generator settings
if ( idValue.getColumnSpan() == 1 ) {
@ -223,7 +221,6 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
}
createGeneratorFrom(
new IdentifierGeneratorDefinition( generatorName, legacyNamedGenerator.getName(), configuration ),
idAttributeMember,
idValue,
(Map) configuration,
buildingContext
@ -231,7 +228,6 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
return;
}
final SequenceGenerator localizedSequencedMatch = GeneratorAnnotationHelper.findLocalizedMatch(
JpaAnnotations.SEQUENCE_GENERATOR,
idAttributeMember,
@ -240,7 +236,7 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
buildingContext
);
if ( localizedSequencedMatch != null ) {
handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, idAttributeMember, buildingContext );
handleSequenceGenerator( generatorName, localizedSequencedMatch, configuration, idValue, buildingContext );
return;
}
@ -252,7 +248,7 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
buildingContext
);
if ( localizedTableMatch != null ) {
handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, idAttributeMember, buildingContext );
handleTableGenerator( generatorName, localizedTableMatch, configuration, idValue, buildingContext );
return;
}
@ -264,19 +260,15 @@ public class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
SequenceGenerator generatorConfig,
Map<String,String> 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 class IdBagIdGeneratorResolverSecondPass implements IdGeneratorResolver {
TableGenerator generatorConfig,
Map<String,String> 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

View File

@ -15,15 +15,14 @@ import org.hibernate.MappingException;
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.SequenceGenerator;
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 class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
public void doSecondPass(Map<String, PersistentClass> 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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
}
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
localizedGenericMatch,
entityMapping,
idValue,
idMember,
buildingContext
);
return;
@ -336,34 +335,35 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
return;
}
final Class<? extends Generator> legacyNamedGenerator = mapLegacyNamedGenerator( generatedValue.generator(), buildingContext );
final String generator = generatedValue.generator();
final Class<? extends Generator> 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<? extends Annotation> metaAnnotated = idMember.getMetaAnnotated( IdGeneratorType.class, buildingContext.getMetadataCollector().getSourceModelBuildingContext() );
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector();
final List<? extends Annotation> 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<String,Object> configuration = new HashMap<>();
GeneratorParameters.collectParameters(
idValue,
buildingContext.getMetadataCollector().getDatabase().getDialect(),
metadataCollector.getDatabase().getDialect(),
entityMapping.getRootClass(),
configuration::put
);
@ -379,21 +379,22 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
}
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
}
private void handleSequenceGenerator(String nameFromGeneratedValue, SequenceGenerator generator) {
final Map<String, Object> configuration = extractConfiguration( nameFromGeneratedValue, generator );
createGeneratorFrom( SequenceStyleGenerator.class, configuration );
createGeneratorFrom( SequenceStyleGenerator.class, extractConfiguration( nameFromGeneratedValue, generator ) );
}
private Map<String,Object> extractConfiguration(String nameFromGenerated, SequenceGenerator generator) {
@ -486,7 +482,7 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
applyCommonConfiguration( configuration, generator );
if ( generator != null ) {
SequenceStyleGenerator.applyConfiguration( generator, idValue, configuration::put );
SequenceStyleGenerator.applyConfiguration( generator, configuration::put );
}
return configuration;
@ -511,13 +507,11 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
// 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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
}
private void handleTableGenerator(String nameFromGeneratedValue, TableGenerator generator) {
final Map<String, Object> configuration = extractConfiguration( nameFromGeneratedValue, generator );
createGeneratorFrom( org.hibernate.id.enhanced.TableGenerator.class, configuration );
createGeneratorFrom( org.hibernate.id.enhanced.TableGenerator.class,
extractConfiguration( nameFromGeneratedValue, generator ) );
}
private Map<String,Object> extractConfiguration(String nameFromGenerated, TableGenerator generator) {
@ -546,7 +540,7 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
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 @@ public class IdGeneratorResolverSecondPass implements IdGeneratorResolver {
Map<String, Object> 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;
} );
}

View File

@ -14,8 +14,10 @@ import org.hibernate.boot.model.relational.Database;
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 jakarta.persistence.SequenceGenerator;
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 class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
}
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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
handleSequenceGenerator(
entityMapping.getJpaEntityName(),
new SequenceGeneratorJpaAnnotation( buildingContext.getMetadataCollector().getSourceModelBuildingContext() ),
new SequenceGeneratorJpaAnnotation( metadataCollector.getSourceModelBuildingContext() ),
entityMapping,
idValue,
idMember,
@ -122,10 +126,11 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
}
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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
handleSequenceGenerator(
generatedValue.generator(),
new SequenceGeneratorJpaAnnotation( generatedValue.generator(), buildingContext.getMetadataCollector().getSourceModelBuildingContext() ),
new SequenceGeneratorJpaAnnotation( generatedValue.generator(), metadataCollector.getSourceModelBuildingContext() ),
entityMapping,
idValue,
idMember,
@ -158,17 +163,17 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
}
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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
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 SequenceGeneratorRegistration globalSequenceMatch = buildingContext.getMetadataCollector()
.getGlobalRegistrations()
.getSequenceGeneratorRegistrations()
.get( globalRegistrationName );
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector();
final GlobalRegistrations globalRegistrations = metadataCollector.getGlobalRegistrations();
final SequenceGeneratorRegistration globalSequenceMatch =
globalRegistrations.getSequenceGeneratorRegistrations().get( globalRegistrationName );
if ( globalSequenceMatch != null ) {
handleSequenceGenerator(
globalRegistrationName,
@ -237,55 +236,48 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
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<? extends Generator> legacyNamedGenerator = GeneratorStrategies.mapLegacyNamedGenerator( generatedValue.generator(), idValue );
if ( !generator.isEmpty() ) {
final Class<? extends Generator> legacyNamedGenerator = mapLegacyNamedGenerator( generator, idValue );
if ( legacyNamedGenerator != null ) {
final Map<String,String> 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 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
handleSequenceGenerator(
globalRegistrationName,
new SequenceGeneratorJpaAnnotation( generatedValue.generator(), buildingContext.getMetadataCollector().getSourceModelBuildingContext() ),
new SequenceGeneratorJpaAnnotation( generator, metadataCollector.getSourceModelBuildingContext() ),
entityMapping,
idValue,
idMember,
@ -348,14 +340,12 @@ public class StrictIdGeneratorResolverSecondPass implements IdGeneratorResolver
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
);

View File

@ -364,7 +364,7 @@ public class Namespace {
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

View File

@ -8,12 +8,15 @@ import java.util.Properties;
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() );
}
}

View File

@ -31,7 +31,6 @@ import org.hibernate.id.IdentifierGenerator;
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 class SequenceStyleGenerator
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 class SequenceStyleGenerator
* <p>
* 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 @@ public class SequenceStyleGenerator
&& ( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
}
public static void applyConfiguration(SequenceGenerator generatorConfig, SimpleValue idValue, BiConsumer<String,String> configCollector) {
public static void applyConfiguration(SequenceGenerator generatorConfig, BiConsumer<String,String> configCollector) {
if ( !generatorConfig.sequenceName().isEmpty() ) {
configCollector.accept( SEQUENCE_PARAM, generatorConfig.sequenceName() );
}

View File

@ -45,7 +45,6 @@ import org.hibernate.internal.CoreMessageLogger;
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 class TableGenerator implements PersistentIdentifierGenerator {
public static void applyConfiguration(
jakarta.persistence.TableGenerator generatorConfig,
SimpleValue idValue,
Map<String, String> configuration) {
applyConfiguration( generatorConfig, idValue, configuration::put );
}
public static void applyConfiguration(
jakarta.persistence.TableGenerator generatorConfig,
SimpleValue idValue,
BiConsumer<String, String> configurationCollector) {
configurationCollector.accept( CONFIG_PREFER_SEGMENT_PER_ENTITY, "true" );

View File

@ -73,10 +73,9 @@ 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.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 class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
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 class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
};
}
private static Map<String, Generator> createGenerators(
JdbcServices jdbcServices,
SqlStringGenerationContext sqlStringGenerationContext,
MetadataImplementor bootMetamodel) {
private Map<String, Generator> createGenerators(
JdbcServices jdbcServices, MetadataImplementor metamodel, SessionFactoryOptions options) {
final Dialect dialect = jdbcServices.getJdbcEnvironment().getDialect();
final Map<String, Generator> 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 );
}
}

View File

@ -651,17 +651,17 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
}
@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 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable
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,

View File

@ -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();
}

View File

@ -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);
}

View File

@ -13,6 +13,7 @@ import org.hibernate.HibernateException;
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.generator.GeneratorCreationContext;
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 class Property implements Serializable, MetaAttributable {
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 @@ public class Property implements Serializable, MetaAttributable {
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 class Property implements Serializable, MetaAttributable {
public Property getProperty() {
return Property.this;
}
@Override
public SqlStringGenerationContext getSqlStringGenerationContext() {
return context.getSqlStringGenerationContext();
}
}
}

View File

@ -376,10 +376,19 @@ public abstract class SimpleValue implements KeyValue {
}
@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 abstract class SimpleValue implements KeyValue {
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 abstract class SimpleValue implements KeyValue {
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 abstract class SimpleValue implements KeyValue {
@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 abstract class SimpleValue implements KeyValue {
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 abstract class SimpleValue implements KeyValue {
// return collectParameters( (SimpleValue) value, dialect, defaultCatalog, defaultSchema, rootClass );
// }
//
// @Override
// public SqlStringGenerationContext getSqlStringGenerationContext() {
// final Database database = getDatabase();
// return fromExplicit( database.getJdbcEnvironment(), database, defaultCatalog, defaultSchema );
// }
}
}

View File

@ -47,7 +47,6 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
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.BasicValue;
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 @@ public abstract class AbstractCollectionPersister
}
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;
}

View File

@ -91,7 +91,8 @@ public class UnnamedGeneratorTests {
final Generator generator = entityBinding.getIdentifier().createGenerator(
metadata.getDatabase().getDialect(),
entityBinding,
entityBinding.getIdentifierProperty()
entityBinding.getIdentifierProperty(),
null
);
checks.accept( generator );

View File

@ -134,7 +134,7 @@ public class AutoGenerationTypeTests {
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 ) );
}
}