HHH-18337 Account for physical naming strategy when querying db sequence

Introduced new signature for `Configurable#configure` which accepts a `GeneratorCreationContext`.
This commit is contained in:
Marco Belladelli 2024-08-01 10:53:55 +02:00
parent 7402e1a153
commit 4b06bf63cd
20 changed files with 272 additions and 108 deletions

View File

@ -560,7 +560,7 @@ public class GeneratorBinder {
/**
* If the given {@link Generator} also implements {@link Configurable},
* call its {@link Configurable#configure(Type, Properties, ServiceRegistry)
* call its {@link Configurable#configure(GeneratorCreationContext, Properties)
* configure()} method.
*/
private static void callConfigure(
@ -568,15 +568,14 @@ public class GeneratorBinder {
Generator generator,
Map<String, Object> configuration,
SimpleValue identifierValue) {
if ( generator instanceof Configurable ) {
final Configurable configurable = (Configurable) generator;
if ( generator instanceof final Configurable configurable ) {
final Properties parameters = collectParameters(
identifierValue,
creationContext.getDatabase().getDialect(),
creationContext.getRootClass(),
configuration
);
configurable.configure( identifierValue.getType(), parameters, creationContext.getServiceRegistry() );
configurable.configure( creationContext, parameters );
}
}

View File

@ -15,6 +15,7 @@ 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.generator.GeneratorCreationContext;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.OptimizableGenerator;
@ -38,7 +39,7 @@ import java.util.Properties;
/**
* Responsible for setting up the parameters which are passed to
* {@link Configurable#configure(Type, Properties, ServiceRegistry)}
* {@link Configurable#configure(GeneratorCreationContext, Properties)}
* when a {@link Configurable} generator is instantiated.
*
* @since 7.0
@ -51,7 +52,7 @@ public class GeneratorParameters {
/**
* Collect the parameters which should be passed to
* {@link Configurable#configure(Type, Properties, ServiceRegistry)}.
* {@link Configurable#configure(GeneratorCreationContext, Properties)}.
*/
public static Properties collectParameters(
SimpleValue identifierValue,

View File

@ -12,6 +12,7 @@ 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;
/**
* An object passed as a parameter to the constructor or
@ -34,4 +35,7 @@ public interface GeneratorCreationContext {
RootClass getRootClass();
Property getProperty();
default Type getType() {
return getProperty().getType();
}
}

View File

@ -11,6 +11,7 @@ import java.util.Properties;
import org.hibernate.MappingException;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
@ -21,6 +22,13 @@ import org.hibernate.type.Type;
* @author Steve Ebersole
*/
public interface Configurable {
/**
* @deprecated Use {@link #configure(GeneratorCreationContext, Properties)} instead
*/
@Deprecated( since = "7.0", forRemoval = true )
default void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
}
/**
* Configure this instance, given the value of parameters
* specified by the user as XML {@code <param>} elements and
@ -32,13 +40,14 @@ public interface Configurable {
* then this method is always called before
* {@link org.hibernate.boot.model.relational.ExportableProducer#registerExportables(Database)},
*
* @param type The id property type descriptor
* @param creationContext Access to the generator creation context
* @param parameters param values, keyed by parameter name
* @param serviceRegistry Access to service that may be needed.
*
* @throws MappingException when there's something wrong with the given parameters
*/
void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException;
default void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
configure( creationContext.getType(), parameters, creationContext.getServiceRegistry() );
};
/**
* Initializes this instance, pre-generating SQL if necessary.

View File

@ -10,6 +10,7 @@ import java.util.Properties;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
@ -68,7 +69,7 @@ public class ForeignGenerator implements IdentifierGenerator {
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
propertyName = parameters.getProperty( PROPERTY );
entityName = parameters.getProperty( ENTITY_NAME );
if ( propertyName==null ) {

View File

@ -17,6 +17,8 @@ import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.EventType;
import org.hibernate.generator.EventTypeSets;
import org.hibernate.generator.Generator;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.generator.BeforeExecutionGenerator;
import org.hibernate.type.Type;
@ -39,7 +41,7 @@ import static org.hibernate.generator.EventTypeSets.INSERT_ONLY;
* {@code ExportableProducer}, in case the implementation needs to export
* objects to the database as part of the process of schema export.
* <p>
* The {@link #configure(Type, Properties, ServiceRegistry)} method accepts
* The {@link #configure(GeneratorCreationContext, Properties)} method accepts
* a properties object containing named values. These include:
* <ul>
* <li>several "standard" parameters with keys defined as static members of
@ -104,7 +106,7 @@ public interface IdentifierGenerator extends BeforeExecutionGenerator, Exportabl
* for example, a sequence or tables.
* <p>
* This method is called just once, after
* {@link #configure(Type, Properties, ServiceRegistry)}.
* {@link #configure(GeneratorCreationContext, Properties)}.
*
* @param database The database instance
*/

View File

@ -22,6 +22,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.ServiceRegistry;
@ -85,10 +86,10 @@ public class IncrementGenerator implements IdentifierGenerator {
}
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
returnClass = type.getReturnedClass();
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
returnClass = creationContext.getType().getReturnedClass();
final JdbcEnvironment jdbcEnvironment = serviceRegistry.requireService( JdbcEnvironment.class );
final JdbcEnvironment jdbcEnvironment = creationContext.getServiceRegistry().requireService( JdbcEnvironment.class );
final IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
column = parameters.getProperty( COLUMN );

View File

@ -8,6 +8,7 @@ package org.hibernate.id;
import java.util.Properties;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
@ -15,7 +16,7 @@ import org.hibernate.type.Type;
* An {@link IdentifierGenerator} that requires creation of database objects.
* <p>
* All instances have access to a special mapping parameter in their
* {@link #configure(Type, Properties, ServiceRegistry)} method: schema
* {@link #configure(GeneratorCreationContext, Properties)} method: schema
*
* @author Gavin King
* @author Steve Ebersole

View File

@ -8,8 +8,9 @@ package org.hibernate.id;
import org.hibernate.generator.EventType;
import org.hibernate.generator.EventTypeSets;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import java.util.EnumSet;

View File

@ -9,9 +9,9 @@ package org.hibernate.id;
import java.util.Properties;
import org.hibernate.dialect.Dialect;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.generator.OnExecutionGenerator;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import static org.hibernate.generator.internal.NaturalIdHelper.getNaturalIdPropertyNames;
@ -87,7 +87,7 @@ public class SelectGenerator
private String uniqueKeyPropertyName;
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) {
public void configure(GeneratorCreationContext creationContext, Properties parameters) {
uniqueKeyPropertyName = parameters.getProperty( KEY );
}

View File

@ -14,10 +14,10 @@ import org.hibernate.MappingException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.uuid.StandardRandomStrategy;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.UUIDJavaType;
@ -50,7 +50,7 @@ public class UUIDGenerator implements IdentifierGenerator {
private UUIDJavaType.ValueTransformer valueTransformer;
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
// check first for an explicit strategy instance
strategy = (UUIDGenerationStrategy) parameters.get( UUID_GEN_STRATEGY );
@ -60,7 +60,7 @@ public class UUIDGenerator implements IdentifierGenerator {
if ( strategyClassName != null ) {
try {
final Class<?> strategyClass =
serviceRegistry.requireService( ClassLoaderService.class )
creationContext.getServiceRegistry().requireService( ClassLoaderService.class )
.classForName( strategyClassName );
try {
strategy = (UUIDGenerationStrategy) strategyClass.newInstance();
@ -80,6 +80,7 @@ public class UUIDGenerator implements IdentifierGenerator {
strategy = StandardRandomStrategy.INSTANCE;
}
final Type type = creationContext.getType();
if ( UUID.class.isAssignableFrom( type.getReturnedClass() ) ) {
valueTransformer = UUIDJavaType.PassThroughTransformer.INSTANCE;
}

View File

@ -10,9 +10,9 @@ import java.util.Properties;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import static org.hibernate.internal.util.config.ConfigurationHelper.getString;
@ -53,7 +53,7 @@ public class UUIDHexGenerator extends AbstractUUIDGenerator {
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
sep = getString( SEPARATOR, parameters, "" );
}

View File

@ -24,6 +24,7 @@ import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
@ -193,11 +194,12 @@ public class SequenceStyleGenerator
// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
final ServiceRegistry serviceRegistry = creationContext.getServiceRegistry();
final JdbcEnvironment jdbcEnvironment = serviceRegistry.requireService( JdbcEnvironment.class );
final Dialect dialect = jdbcEnvironment.getDialect();
identifierType = type;
this.identifierType = creationContext.getType();
final QualifiedName sequenceName = determineSequenceName( parameters, dialect, jdbcEnvironment, serviceRegistry );
final int initialValue = determineInitialValue( parameters );
@ -214,7 +216,8 @@ public class SequenceStyleGenerator
physicalSequence,
optimizationStrategy,
serviceRegistry,
determineContributor( parameters )
determineContributor( parameters ),
creationContext
);
if ( physicalSequence
@ -224,8 +227,8 @@ public class SequenceStyleGenerator
LOG.forcingTableUse();
}
databaseStructure = buildDatabaseStructure(
type,
this.databaseStructure = buildDatabaseStructure(
identifierType,
parameters,
jdbcEnvironment,
forceTableUse,
@ -251,7 +254,8 @@ public class SequenceStyleGenerator
boolean physicalSequence,
OptimizerDescriptor optimizationStrategy,
ServiceRegistry serviceRegistry,
String contributor) {
String contributor,
GeneratorCreationContext creationContext) {
final ConfigurationService configurationService = serviceRegistry.requireService( ConfigurationService.class );
final SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
@ -262,7 +266,13 @@ public class SequenceStyleGenerator
if ( sequenceMismatchStrategy != SequenceMismatchStrategy.NONE
&& optimizationStrategy.isPooled()
&& physicalSequence ) {
final String databaseSequenceName = sequenceName.getObjectName().getText();
final Database database = creationContext.getDatabase();
final String databaseSequenceName = database != null ?
database.getPhysicalNamingStrategy().toPhysicalSequenceName(
sequenceName.getObjectName(),
jdbcEnvironment
).getText() :
sequenceName.getObjectName().getText();
final Number databaseIncrementValue =
isSchemaToBeRecreated( contributor, configurationService ) ? null
: getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );

View File

@ -36,6 +36,7 @@ import org.hibernate.engine.spi.SessionEventListenerManager;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.spi.EventManager;
import org.hibernate.event.spi.HibernateMonitoringEvent;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.ExportableColumn;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
@ -332,10 +333,11 @@ public class TableGenerator implements PersistentIdentifierGenerator {
}
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
public void configure(GeneratorCreationContext creationContext, Properties parameters) throws MappingException {
final ServiceRegistry serviceRegistry = creationContext.getServiceRegistry();
storeLastUsedValue = serviceRegistry.requireService( ConfigurationService.class )
.getSetting( AvailableSettings.TABLE_GENERATOR_STORE_LAST_USED, StandardConverters.BOOLEAN, true );
identifierType = type;
identifierType = creationContext.getType();
final JdbcEnvironment jdbcEnvironment = serviceRegistry.requireService( JdbcEnvironment.class );

View File

@ -1051,6 +1051,11 @@ public abstract class SimpleValue implements KeyValue {
return rootClass.getIdentifierProperty();
}
@Override
public Type getType() {
return SimpleValue.this.getType();
}
// we could add these if it helps integrate old infrastructure
// @Override
// public Properties getParameters() {

View File

@ -11,15 +11,23 @@ import java.util.Properties;
import org.hibernate.Session;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.hibernate.testing.orm.junit.BaseUnitTest;
@ -27,6 +35,7 @@ import org.hibernate.testing.orm.junit.DialectFeatureChecks.SupportsSequences;
import org.hibernate.testing.orm.junit.RequiresDialectFeature;
import org.hibernate.testing.transaction.TransactionUtil;
import org.hibernate.testing.util.ServiceRegistryUtil;
import org.hibernate.testing.util.uuid.IdGeneratorCreationContext;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -63,12 +72,51 @@ public class SequenceStyleGeneratorBehavesLikeSequeceHiloGeneratorWitZeroIncreme
properties.setProperty( SequenceStyleGenerator.OPT_PARAM, "legacy-hilo" );
properties.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "0" ); // JPA allocationSize of 1
generator.configure(
buildingContext.getBootstrapContext()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
properties,
serviceRegistry
new GeneratorCreationContext() {
@Override
public Database getDatabase() {
return buildingContext.getMetadataCollector().getDatabase();
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
@Override
public String getDefaultCatalog() {
return "";
}
@Override
public String getDefaultSchema() {
return "";
}
@Override
public PersistentClass getPersistentClass() {
return null;
}
@Override
public RootClass getRootClass() {
return null;
}
@Override
public Property getProperty() {
return null;
}
@Override
public Type getType() {
return buildingContext.getBootstrapContext()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG );
}
},
properties
);
final Metadata metadata = new MetadataSources( serviceRegistry ).buildMetadata();

View File

@ -12,6 +12,7 @@ import org.hibernate.boot.model.relational.Database;
import org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.DatabaseVersion;
@ -19,6 +20,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.sequence.ANSISequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.OptimizableGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.enhanced.DatabaseStructure;
@ -32,12 +34,18 @@ import org.hibernate.id.enhanced.SequenceStructure;
import org.hibernate.id.enhanced.SequenceStyleGenerator;
import org.hibernate.id.enhanced.StandardOptimizerDescriptor;
import org.hibernate.id.enhanced.TableStructure;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.testing.boot.MetadataBuildingContextTestingImpl;
import org.hibernate.testing.orm.junit.BaseUnitTest;
import org.hibernate.testing.util.ServiceRegistryUtil;
import org.hibernate.testing.util.uuid.IdGeneratorCreationContext;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.instanceOf;
@ -55,6 +63,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
*/
@BaseUnitTest
public class SequenceStyleConfigUnitTest {
private static final Type LONG_TYPE = new TypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.LONG );
/**
* Test all params defaulted with a dialect supporting pooled sequences
@ -72,10 +81,8 @@ public class SequenceStyleConfigUnitTest {
Properties props = buildGeneratorPropertiesBase( buildingContext );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
@ -118,10 +125,8 @@ public class SequenceStyleConfigUnitTest {
Properties props = buildGeneratorPropertiesBase( buildingContext );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
@ -160,10 +165,8 @@ public class SequenceStyleConfigUnitTest {
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
@ -190,10 +193,8 @@ public class SequenceStyleConfigUnitTest {
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
generator.registerExportables( database );
@ -226,10 +227,8 @@ public class SequenceStyleConfigUnitTest {
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
generator.registerExportables( database );
@ -260,10 +259,8 @@ public class SequenceStyleConfigUnitTest {
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
new TestGeneratorCreationContext( LONG_TYPE, buildingContext, serviceRegistry ),
props
);
Database database = new Database( buildingContext.getBuildingOptions() );
generator.registerExportables( database );
@ -294,16 +291,16 @@ public class SequenceStyleConfigUnitTest {
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
final GeneratorCreationContext creationContext = new TestGeneratorCreationContext(
LONG_TYPE,
buildingContext,
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.OPT_PARAM, StandardOptimizerDescriptor.NONE.getExternalName() );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
Database database = new Database( buildingContext.getBuildingOptions() );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
@ -318,12 +315,7 @@ public class SequenceStyleConfigUnitTest {
props.setProperty( SequenceStyleGenerator.OPT_PARAM, StandardOptimizerDescriptor.HILO.getExternalName() );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
@ -336,12 +328,7 @@ public class SequenceStyleConfigUnitTest {
props.setProperty( SequenceStyleGenerator.OPT_PARAM, StandardOptimizerDescriptor.POOLED.getExternalName() );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
// because the dialect reports to not support pooled seqyences, the expectation is that we will
@ -363,15 +350,15 @@ public class SequenceStyleConfigUnitTest {
() -> buildingContext.getBootstrapContext().getTypeConfiguration(),
serviceRegistry
);
final GeneratorCreationContext creationContext = new TestGeneratorCreationContext(
LONG_TYPE,
buildingContext,
serviceRegistry
);
Properties props = buildGeneratorPropertiesBase( buildingContext );
props.setProperty( SequenceStyleGenerator.INCREMENT_PARAM, "20" );
SequenceStyleGenerator generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
Database database = new Database( buildingContext.getBuildingOptions() );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
@ -380,12 +367,7 @@ public class SequenceStyleConfigUnitTest {
props.setProperty( Environment.PREFERRED_POOLED_OPTIMIZER, StandardOptimizerDescriptor.POOLED_LO.getExternalName() );
generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
@ -393,12 +375,7 @@ public class SequenceStyleConfigUnitTest {
props.setProperty( Environment.PREFERRED_POOLED_OPTIMIZER, StandardOptimizerDescriptor.POOLED_LOTL.getExternalName() );
generator = new SequenceStyleGenerator();
generator.configure(
new TypeConfiguration().getBasicTypeRegistry()
.resolve( StandardBasicTypes.LONG ),
props,
serviceRegistry
);
generator.configure( creationContext, props );
generator.registerExportables( database );
generator.initialize( SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment() ) );
assertClassAssignability( SequenceStructure.class, generator.getDatabaseStructure().getClass() );
@ -437,4 +414,55 @@ public class SequenceStyleConfigUnitTest {
}
}
private static class TestGeneratorCreationContext implements GeneratorCreationContext {
private final Type type;
private final MetadataImplementor metadata;
private final ServiceRegistry serviceRegistry;
public TestGeneratorCreationContext(Type type, MetadataBuildingContext buildingContext, ServiceRegistry serviceRegistry) {
this.type = type;
this.metadata = buildingContext.getMetadataCollector();
this.serviceRegistry = serviceRegistry;
}
@Override
public Database getDatabase() {
return metadata.getDatabase();
}
@Override
public ServiceRegistry getServiceRegistry() {
return serviceRegistry;
}
@Override
public String getDefaultCatalog() {
return "";
}
@Override
public String getDefaultSchema() {
return "";
}
@Override
public PersistentClass getPersistentClass() {
return null;
}
@Override
public RootClass getRootClass() {
return null;
}
@Override
public Property getProperty() {
return null;
}
@Override
public Type getType() {
return type;
}
}
}

View File

@ -15,14 +15,22 @@ 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.boot.spi.MetadataImplementor;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.generator.GeneratorCreationContext;
import org.hibernate.id.enhanced.TableGenerator;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.Table;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.util.ServiceRegistryUtil;
import org.hibernate.testing.util.uuid.IdGeneratorCreationContext;
import org.junit.jupiter.api.Test;
import static org.hamcrest.Matchers.containsString;
@ -38,19 +46,58 @@ public class Db2GenerationTest {
.build();
try {
final Metadata metadata = new MetadataSources( ssr ).buildMetadata();
final MetadataImplementor metadata = (MetadataImplementor) new MetadataSources( ssr ).buildMetadata();
assertEquals( 0, metadata.getDatabase().getDefaultNamespace().getTables().size() );
final TableGenerator generator = new TableGenerator();
generator.configure(
metadata.getDatabase()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER ),
new Properties(),
ssr
new GeneratorCreationContext() {
@Override
public Database getDatabase() {
return metadata.getDatabase();
}
@Override
public ServiceRegistry getServiceRegistry() {
return ssr;
}
@Override
public String getDefaultCatalog() {
return "";
}
@Override
public String getDefaultSchema() {
return "";
}
@Override
public PersistentClass getPersistentClass() {
return null;
}
@Override
public RootClass getRootClass() {
return null;
}
@Override
public Property getProperty() {
return null;
}
@Override
public Type getType() {
return metadata.getDatabase()
.getTypeConfiguration()
.getBasicTypeRegistry()
.resolve( StandardBasicTypes.INTEGER );
}
},
new Properties()
);
generator.registerExportables( metadata.getDatabase() );

View File

@ -53,9 +53,9 @@ public class NativeGenerator
}
@Override
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) {
public void configure(GeneratorCreationContext creationContext, Properties parameters) {
if ( generator instanceof Configurable ) {
((Configurable) generator).configure( type, parameters, serviceRegistry );
((Configurable) generator).configure( creationContext, parameters );
}
}

View File

@ -240,6 +240,10 @@ specify a name for JNDI binding. The new behavior is as follows (assuming `hibe
Hibernate can use the persistence-unit name for binding into JNDI as well, but `hibernate.session_factory_name_is_jndi`
must be explicitly set to true.
[[configurable-generators]]
== Configurable generators
The signature of the `Configurable#configure` method changed from accepting just a `ServiceRegistry` instance to the new `GeneratorCreationContext` interface, which exposes a lot more useful information when configuring the generator itself. The old signature has been deprecated for removal, so you should migrate any custom `Configurable` generator implementation to the new one.
[[hbm-transform]]
== hbm.xml Transformation