HHH-15789 change IdentifierGeneratorFactory to be able to produce plain InMemoryGenerators
this change is sort-of breaky, so I'm not sure about it cleanups to StandardIdentifierGeneratorFactory squash
This commit is contained in:
parent
cced19c7ee
commit
a8aab7f5f2
|
@ -74,7 +74,8 @@ public @interface GenericGenerator {
|
|||
*/
|
||||
String name();
|
||||
/**
|
||||
* The type of identifier generator, a class implementing {@link InMemoryGenerator}.
|
||||
* The type of identifier generator, a class implementing {@link InMemoryGenerator}
|
||||
* or, more commonly, {@link org.hibernate.id.IdentifierGenerator}.
|
||||
*
|
||||
* @since 6.2
|
||||
*/
|
||||
|
@ -83,7 +84,8 @@ public @interface GenericGenerator {
|
|||
* The type of identifier generator, the name of either:
|
||||
* <ul>
|
||||
* <li>a built-in Hibernate id generator, or
|
||||
* <li>a custom class implementing {@link org.hibernate.id.IdentifierGenerator}.
|
||||
* <li>a custom class implementing {@link InMemoryGenerator}, or, more commonly,
|
||||
* {@link org.hibernate.id.IdentifierGenerator}.
|
||||
* </ul>
|
||||
*
|
||||
* @deprecated use {@link #type()} for typesafety
|
||||
|
|
|
@ -10,7 +10,6 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
|
@ -18,12 +17,12 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
|
||||
/**
|
||||
* Meta-annotation used to mark another annotation as providing configuration
|
||||
* for a custom {@link IdentifierGenerator}. This is the best way to work with
|
||||
* customized identifier generation in Hibernate.
|
||||
* for a custom {@linkplain InMemoryGenerator identifier generator}. This is
|
||||
* the best way to work with customized identifier generation in Hibernate.
|
||||
* <p>
|
||||
* For example, if we have a custom identifier generator:
|
||||
* <pre>{@code
|
||||
* public class CustomSequenceGenerator implements IdentifierGenerator {
|
||||
* public class CustomSequenceGenerator implements InMemoryGenerator {
|
||||
* public CustomSequenceGenerator(CustomSequence config, Member annotatedMember,
|
||||
* CustomIdGeneratorCreationContext context) {
|
||||
* ...
|
||||
|
|
|
@ -20,8 +20,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||
|
||||
/**
|
||||
* Meta-annotation used to mark another annotation as providing configuration
|
||||
* for a custom {@linkplain Generator value generation strategy}.
|
||||
* This is the best way to work with customized value generation in Hibernate.
|
||||
* for a custom {@linkplain Generator value generation strategy}. This is the
|
||||
* best way to work with customized value generation in Hibernate.
|
||||
* <p>
|
||||
* For example, if we have a custom value generator:
|
||||
* <pre>{@code
|
||||
|
|
|
@ -78,7 +78,6 @@ import org.hibernate.cfg.annotations.NamedEntityGraphDefinition;
|
|||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.spi.FilterDefinition;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
@ -2316,7 +2315,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector
|
|||
// It was done this way in the old code too, so no "regression" here; but
|
||||
// it could be done better
|
||||
try {
|
||||
final InMemoryGenerator generator = identifierValueBinding.createIdentifierGenerator(
|
||||
final InMemoryGenerator generator = identifierValueBinding.createGenerator(
|
||||
bootstrapContext.getIdentifierGeneratorFactory(),
|
||||
dialect,
|
||||
entityBinding
|
||||
|
|
|
@ -39,8 +39,8 @@ public class Assigned implements StandardGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
entityName = params.getProperty( ENTITY_NAME );
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
entityName = parameters.getProperty( ENTITY_NAME );
|
||||
if ( entityName == null ) {
|
||||
throw new MappingException("no entity name");
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ public class ForeignGenerator implements StandardGenerator {
|
|||
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
propertyName = params.getProperty( "property" );
|
||||
entityName = params.getProperty( ENTITY_NAME );
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
propertyName = parameters.getProperty( "property" );
|
||||
entityName = parameters.getProperty( ENTITY_NAME );
|
||||
if ( propertyName==null ) {
|
||||
throw new MappingException( "param named \"property\" is required for foreign id generation strategy" );
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import static org.hibernate.tuple.GenerationTiming.INSERT;
|
|||
* <p>
|
||||
* This interface extends {@code InMemoryGenerator} with some additional
|
||||
* machinery for {@linkplain #configure configuration}, and for caching
|
||||
* {@link #initialize(SqlStringGenerationContext) generated SQL}.
|
||||
* {@linkplain #initialize(SqlStringGenerationContext) generated SQL}.
|
||||
* <p>
|
||||
* Any identifier generator, including a generator which directly implements
|
||||
* {@code InMemoryGenerator}, may also implement {@link ExportableProducer}.
|
||||
|
@ -42,11 +42,15 @@ import static org.hibernate.tuple.GenerationTiming.INSERT;
|
|||
* <li>several "standard" parameters with keys defined as static members of
|
||||
* this interface: {@value #ENTITY_NAME}, {@value #JPA_ENTITY_NAME},
|
||||
* {@value #GENERATOR_NAME}, {@value #CONTRIBUTOR_NAME}, along with
|
||||
* <li>additional parameters supplied by Hibernate to its built-in generators,
|
||||
* depending on the generator class, and, possibly,
|
||||
* <li>additional hardcoded parameters supplied by Hibernate to its built-in
|
||||
* generators, depending on the generator class, and, possibly,
|
||||
* <li>{@linkplain org.hibernate.annotations.Parameter parameters} specified
|
||||
* using {@link org.hibernate.annotations.GenericGenerator#parameters()}.
|
||||
* </ul>
|
||||
* Instances of {@code IdentifierGenerator} are usually created and configured
|
||||
* by the {@link org.hibernate.id.factory.IdentifierGeneratorFactory} service.
|
||||
* It is not usually correct to use an {@code IdentifierGenerator} with the
|
||||
* {@link org.hibernate.annotations.IdGeneratorType} meta-annotation.
|
||||
*
|
||||
* @author Gavin King
|
||||
*
|
||||
|
@ -85,12 +89,12 @@ public interface IdentifierGenerator extends InMemoryGenerator, ExportableProduc
|
|||
* and before {@link #registerExportables(Database)}.
|
||||
*
|
||||
* @param type The id property type descriptor
|
||||
* @param params param values, keyed by parameter name
|
||||
* @param parameters param values, keyed by parameter name
|
||||
* @param serviceRegistry Access to service that may be needed.
|
||||
* @throws MappingException If configuration fails.
|
||||
*/
|
||||
@Override
|
||||
default void configure(Type type, Properties params, ServiceRegistry serviceRegistry) {
|
||||
default void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,31 +71,31 @@ public class IncrementGenerator implements StandardGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
returnClass = type.getReturnedClass();
|
||||
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
final ObjectNameNormalizer normalizer =
|
||||
(ObjectNameNormalizer) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );
|
||||
(ObjectNameNormalizer) parameters.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );
|
||||
|
||||
column = params.getProperty( "column" );
|
||||
column = parameters.getProperty( "column" );
|
||||
if ( column == null ) {
|
||||
column = params.getProperty( PersistentIdentifierGenerator.PK );
|
||||
column = parameters.getProperty( PersistentIdentifierGenerator.PK );
|
||||
}
|
||||
column = normalizer.normalizeIdentifierQuoting( column ).render( jdbcEnvironment.getDialect() );
|
||||
|
||||
IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
|
||||
|
||||
final String schema = normalizer.toDatabaseIdentifierText(
|
||||
params.getProperty( PersistentIdentifierGenerator.SCHEMA )
|
||||
parameters.getProperty( PersistentIdentifierGenerator.SCHEMA )
|
||||
);
|
||||
final String catalog = normalizer.toDatabaseIdentifierText(
|
||||
params.getProperty( PersistentIdentifierGenerator.CATALOG )
|
||||
parameters.getProperty( PersistentIdentifierGenerator.CATALOG )
|
||||
);
|
||||
|
||||
String tableList = params.getProperty( "tables" );
|
||||
String tableList = parameters.getProperty( "tables" );
|
||||
if ( tableList == null ) {
|
||||
tableList = params.getProperty( PersistentIdentifierGenerator.TABLES );
|
||||
tableList = parameters.getProperty( PersistentIdentifierGenerator.TABLES );
|
||||
}
|
||||
physicalTableNames = new ArrayList<>();
|
||||
for ( String tableName : StringHelper.split( ", ", tableList ) ) {
|
||||
|
|
|
@ -42,8 +42,8 @@ public class SelectGenerator extends AbstractPostInsertGenerator {
|
|||
private String uniqueKeyPropertyName;
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
uniqueKeyPropertyName = params.getProperty( "key" );
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
uniqueKeyPropertyName = parameters.getProperty( "key" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -51,13 +51,13 @@ public class UUIDGenerator implements StandardGenerator {
|
|||
private UUIDJavaType.ValueTransformer valueTransformer;
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
// check first for an explicit strategy instance
|
||||
strategy = (UUIDGenerationStrategy) params.get( UUID_GEN_STRATEGY );
|
||||
strategy = (UUIDGenerationStrategy) parameters.get( UUID_GEN_STRATEGY );
|
||||
|
||||
if ( strategy == null ) {
|
||||
// next check for an explicit strategy class
|
||||
final String strategyClassName = params.getProperty( UUID_GEN_STRATEGY_CLASS );
|
||||
final String strategyClassName = parameters.getProperty( UUID_GEN_STRATEGY_CLASS );
|
||||
if ( strategyClassName != null ) {
|
||||
try {
|
||||
final ClassLoaderService cls = serviceRegistry.getService( ClassLoaderService.class );
|
||||
|
|
|
@ -44,8 +44,8 @@ public class UUIDHexGenerator extends AbstractUUIDGenerator {
|
|||
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
sep = ConfigurationHelper.getString( "separator", params, "" );
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
sep = ConfigurationHelper.getString( "separator", parameters, "" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -180,21 +180,21 @@ public class SequenceStyleGenerator
|
|||
// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
|
||||
final Dialect dialect = jdbcEnvironment.getDialect();
|
||||
|
||||
this.identifierType = type;
|
||||
boolean forceTableUse = ConfigurationHelper.getBoolean( FORCE_TBL_PARAM, params, false );
|
||||
boolean forceTableUse = ConfigurationHelper.getBoolean( FORCE_TBL_PARAM, parameters, false );
|
||||
|
||||
final QualifiedName sequenceName = determineSequenceName( params, dialect, jdbcEnvironment, serviceRegistry );
|
||||
final QualifiedName sequenceName = determineSequenceName(parameters, dialect, jdbcEnvironment, serviceRegistry );
|
||||
|
||||
final int initialValue = determineInitialValue( params );
|
||||
int incrementSize = determineIncrementSize( params );
|
||||
final int initialValue = determineInitialValue(parameters);
|
||||
int incrementSize = determineIncrementSize(parameters);
|
||||
|
||||
final String optimizationStrategy = determineOptimizationStrategy( params, incrementSize );
|
||||
final String optimizationStrategy = determineOptimizationStrategy(parameters, incrementSize );
|
||||
|
||||
final boolean isPooledOptimizer = OptimizerFactory.isPooledOptimizer( optimizationStrategy );
|
||||
|
||||
|
@ -242,7 +242,7 @@ public class SequenceStyleGenerator
|
|||
|
||||
this.databaseStructure = buildDatabaseStructure(
|
||||
type,
|
||||
params,
|
||||
parameters,
|
||||
jdbcEnvironment,
|
||||
forceTableUse,
|
||||
sequenceName,
|
||||
|
@ -253,7 +253,7 @@ public class SequenceStyleGenerator
|
|||
optimizationStrategy,
|
||||
identifierType.getReturnedClass(),
|
||||
incrementSize,
|
||||
ConfigurationHelper.getInt( INITIAL_PARAM, params, -1 )
|
||||
ConfigurationHelper.getInt( INITIAL_PARAM, parameters, -1 )
|
||||
);
|
||||
this.databaseStructure.configure( optimizer );
|
||||
}
|
||||
|
|
|
@ -326,29 +326,29 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
public void configure(Type type, Properties parameters, ServiceRegistry serviceRegistry) throws MappingException {
|
||||
storeLastUsedValue = serviceRegistry.getService( ConfigurationService.class )
|
||||
.getSetting( AvailableSettings.TABLE_GENERATOR_STORE_LAST_USED, StandardConverters.BOOLEAN, true );
|
||||
identifierType = type;
|
||||
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
|
||||
qualifiedTableName = determineGeneratorTableName( params, jdbcEnvironment, serviceRegistry );
|
||||
segmentColumnName = determineSegmentColumnName( params, jdbcEnvironment );
|
||||
valueColumnName = determineValueColumnName( params, jdbcEnvironment );
|
||||
qualifiedTableName = determineGeneratorTableName(parameters, jdbcEnvironment, serviceRegistry );
|
||||
segmentColumnName = determineSegmentColumnName(parameters, jdbcEnvironment );
|
||||
valueColumnName = determineValueColumnName(parameters, jdbcEnvironment );
|
||||
|
||||
segmentValue = determineSegmentValue( params );
|
||||
segmentValue = determineSegmentValue(parameters);
|
||||
|
||||
segmentValueLength = determineSegmentColumnSize( params );
|
||||
initialValue = determineInitialValue( params );
|
||||
incrementSize = determineIncrementSize( params );
|
||||
segmentValueLength = determineSegmentColumnSize(parameters);
|
||||
initialValue = determineInitialValue(parameters);
|
||||
incrementSize = determineIncrementSize(parameters);
|
||||
|
||||
final String optimizationStrategy = ConfigurationHelper.getString(
|
||||
OPT_PARAM,
|
||||
params,
|
||||
OptimizerFactory.determineImplicitOptimizerName( incrementSize, params )
|
||||
parameters,
|
||||
OptimizerFactory.determineImplicitOptimizerName( incrementSize, parameters)
|
||||
);
|
||||
int optimizerInitialValue = ConfigurationHelper.getInt( INITIAL_PARAM, params, -1 );
|
||||
int optimizerInitialValue = ConfigurationHelper.getInt( INITIAL_PARAM, parameters, -1 );
|
||||
optimizer = OptimizerFactory.buildOptimizer(
|
||||
optimizationStrategy,
|
||||
identifierType.getReturnedClass(),
|
||||
|
@ -356,7 +356,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
optimizerInitialValue
|
||||
);
|
||||
|
||||
contributor = params.getProperty( CONTRIBUTOR_NAME );
|
||||
contributor = parameters.getProperty( CONTRIBUTOR_NAME );
|
||||
if ( contributor == null ) {
|
||||
contributor = "orm";
|
||||
}
|
||||
|
|
|
@ -8,25 +8,49 @@ package org.hibernate.id.factory;
|
|||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.id.IdentifierGenerator;
|
||||
import org.hibernate.id.factory.spi.GeneratorDefinitionResolver;
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
import jakarta.persistence.GenerationType;
|
||||
|
||||
/**
|
||||
* Contract for a {@code factory} of {@link IdentifierGenerator} instances.
|
||||
* Contract for a factory of {@link IdentifierGenerator} instances. The implementor
|
||||
* of this service is responsible for providing implementations of the predefined
|
||||
* built-in id generators, all of which implement {@link IdentifierGenerator}, along
|
||||
* with any id generator declared using {@link org.hibernate.annotations.GenericGenerator}.
|
||||
* <p>
|
||||
* An id generator is identified by either:
|
||||
* <ul>
|
||||
* <li>a predefined string-based name (which originated in the old {@code hbm.xml}
|
||||
* mapping file format),
|
||||
* <li>the {@link org.hibernate.annotations.GenericGenerator#name name} or the
|
||||
* the {@link org.hibernate.annotations.GenericGenerator#type type} specified
|
||||
* by the {@code @GenericGenerator} annotation, or
|
||||
* <li>a JPA-defined {@link GenerationType}.
|
||||
* </ul>
|
||||
* A new generator passed a {@link Properties} object containing parameters via the
|
||||
* method {@link IdentifierGenerator#configure(Type, Properties, ServiceRegistry)}.
|
||||
* <p>
|
||||
* This is part of an older mechanism for instantiating and configuring id generators
|
||||
* which predates the existence of {@link org.hibernate.tuple.Generator} and the
|
||||
* {@link org.hibernate.annotations.IdGeneratorType @IdGeneratorType} meta-annotation.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@Incubating //this API is currently in flux
|
||||
public interface IdentifierGeneratorFactory extends Service {
|
||||
/**
|
||||
* Create an IdentifierGenerator based on the given details
|
||||
* Create an {@link IdentifierGenerator} based on the given details.
|
||||
*/
|
||||
IdentifierGenerator createIdentifierGenerator(
|
||||
@Incubating
|
||||
InMemoryGenerator createIdentifierGenerator(
|
||||
GenerationType generationType,
|
||||
String generatedValueGeneratorName,
|
||||
String generatorName,
|
||||
|
@ -39,7 +63,7 @@ public interface IdentifierGeneratorFactory extends Service {
|
|||
*
|
||||
* @param strategy The generation strategy.
|
||||
* @param type The mapping type for the identifier values.
|
||||
* @param config Any configuration properties given in the generator mapping.
|
||||
* @param parameters Any parameters properties given in the generator mapping.
|
||||
*
|
||||
* @return The appropriate generator instance.
|
||||
*
|
||||
|
@ -47,7 +71,7 @@ public interface IdentifierGeneratorFactory extends Service {
|
|||
* instead
|
||||
*/
|
||||
@Deprecated(since = "6.0")
|
||||
IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config);
|
||||
InMemoryGenerator createIdentifierGenerator(String strategy, Type type, Properties parameters);
|
||||
|
||||
/**
|
||||
* Retrieve the class that will be used as the {@link IdentifierGenerator} for the given strategy.
|
||||
|
@ -59,7 +83,7 @@ public interface IdentifierGeneratorFactory extends Service {
|
|||
* {@link #createIdentifierGenerator(GenerationType, String, String, JavaType, Properties, GeneratorDefinitionResolver)}
|
||||
*/
|
||||
@Deprecated(since = "6.0")
|
||||
Class<?> getIdentifierGeneratorClass(String strategy);
|
||||
Class<? extends InMemoryGenerator> getIdentifierGeneratorClass(String strategy);
|
||||
|
||||
/**
|
||||
* Get the dialect.
|
||||
|
|
|
@ -20,12 +20,13 @@ import org.hibernate.mapping.Column;
|
|||
import org.hibernate.mapping.RootClass;
|
||||
import org.hibernate.mapping.SimpleValue;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class IdentifierGeneratorUtil {
|
||||
|
||||
public static IdentifierGenerator createLegacyIdentifierGenerator(
|
||||
public static InMemoryGenerator createLegacyIdentifierGenerator(
|
||||
SimpleValue simpleValue,
|
||||
IdentifierGeneratorFactory identifierGeneratorFactory,
|
||||
Dialect dialect,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.id.factory.internal;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -18,7 +17,6 @@ import org.hibernate.NotYetImplementedFor6Exception;
|
|||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
|
||||
|
@ -41,22 +39,24 @@ import org.hibernate.id.factory.spi.StandardGenerator;
|
|||
import org.hibernate.internal.log.DeprecationLogger;
|
||||
import org.hibernate.jpa.spi.IdentifierGeneratorStrategyProvider;
|
||||
import org.hibernate.resource.beans.container.spi.BeanContainer;
|
||||
import org.hibernate.resource.beans.container.spi.ContainedBean;
|
||||
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
|
||||
import org.hibernate.resource.beans.internal.Helper;
|
||||
import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.Type;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER;
|
||||
import static org.hibernate.id.factory.IdGenFactoryLogging.ID_GEN_FAC_LOGGER;
|
||||
|
||||
/**
|
||||
* Basic implementation of {@link org.hibernate.id.factory.IdentifierGeneratorFactory}.
|
||||
* Basic implementation of {@link org.hibernate.id.factory.IdentifierGeneratorFactory},
|
||||
* responsible for instantiating the predefined built-in id generators, and generators
|
||||
* declared using {@link org.hibernate.annotations.GenericGenerator}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings( { "deprecation" ,"rawtypes" } )
|
||||
public class StandardIdentifierGeneratorFactory
|
||||
implements IdentifierGeneratorFactory, BeanContainer.LifecycleOptions, Serializable {
|
||||
|
||||
|
@ -77,23 +77,32 @@ public class StandardIdentifierGeneratorFactory
|
|||
}
|
||||
|
||||
/**
|
||||
* Constructs a new factory, explicitly controlling whether to use
|
||||
* CDI or not
|
||||
* Constructs a new factory, explicitly controlling whether to use CDI or not
|
||||
*/
|
||||
public StandardIdentifierGeneratorFactory(ServiceRegistry serviceRegistry, boolean ignoreBeanContainer) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
beanContainer = getBeanContainer( serviceRegistry, ignoreBeanContainer );
|
||||
registerJpaGenerators();
|
||||
logOverrides();
|
||||
registerPredefinedGenerators();
|
||||
registerUsingLegacyContributor();
|
||||
}
|
||||
|
||||
if ( ignoreBeanContainer ) {
|
||||
private static BeanContainer getBeanContainer(ServiceRegistry serviceRegistry, boolean ignoreBeanContainer) {
|
||||
if (ignoreBeanContainer) {
|
||||
ID_GEN_FAC_LOGGER.debug( "Ignoring CDI for resolving IdentifierGenerator instances as extended or delayed CDI support was enabled" );
|
||||
this.beanContainer = null;
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
this.beanContainer = serviceRegistry.getService( ManagedBeanRegistry.class ).getBeanContainer();
|
||||
final BeanContainer beanContainer = serviceRegistry.getService( ManagedBeanRegistry.class ).getBeanContainer();
|
||||
if ( beanContainer == null ) {
|
||||
ID_GEN_FAC_LOGGER.debug( "Resolving IdentifierGenerator instances will not use CDI as it was not configured" );
|
||||
}
|
||||
return beanContainer;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerJpaGenerators() {
|
||||
generatorTypeStrategyMap.put( GenerationType.AUTO, AutoGenerationTypeStrategy.INSTANCE );
|
||||
generatorTypeStrategyMap.put( GenerationType.SEQUENCE, SequenceGenerationTypeStrategy.INSTANCE );
|
||||
generatorTypeStrategyMap.put( GenerationType.TABLE, TableGenerationTypeStrategy.INSTANCE );
|
||||
|
@ -101,30 +110,31 @@ public class StandardIdentifierGeneratorFactory
|
|||
try {
|
||||
generatorTypeStrategyMap.put( GenerationType.valueOf( "UUID" ), UUIDGenerationTypeStrategy.INSTANCE );
|
||||
}
|
||||
catch (IllegalArgumentException ex) {
|
||||
// Ignore
|
||||
catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
final ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
final Collection<GenerationTypeStrategyRegistration> generationTypeStrategyRegistrations = classLoaderService.loadJavaServices( GenerationTypeStrategyRegistration.class );
|
||||
generationTypeStrategyRegistrations.forEach( (registration) -> registration.registerStrategies(
|
||||
(generationType, generationTypeStrategy) -> {
|
||||
final GenerationTypeStrategy previous = generatorTypeStrategyMap.put(
|
||||
generationType,
|
||||
generationTypeStrategy
|
||||
);
|
||||
if ( previous != null ) {
|
||||
ID_GEN_FAC_LOGGER.debugf(
|
||||
"GenerationTypeStrategyRegistration [%s] overrode previous registration for GenerationType#%s : %s",
|
||||
registration,
|
||||
generationType.name(),
|
||||
previous
|
||||
);
|
||||
}
|
||||
},
|
||||
serviceRegistry
|
||||
) );
|
||||
private void logOverrides() {
|
||||
serviceRegistry.getService( ClassLoaderService.class )
|
||||
.loadJavaServices( GenerationTypeStrategyRegistration.class )
|
||||
.forEach( (registration) -> registration.registerStrategies(
|
||||
(generationType, generationTypeStrategy) -> {
|
||||
final GenerationTypeStrategy previous =
|
||||
generatorTypeStrategyMap.put( generationType, generationTypeStrategy );
|
||||
if ( previous != null ) {
|
||||
ID_GEN_FAC_LOGGER.debugf(
|
||||
"GenerationTypeStrategyRegistration [%s] overrode previous registration for GenerationType#%s : %s",
|
||||
registration,
|
||||
generationType.name(),
|
||||
previous
|
||||
);
|
||||
}
|
||||
},
|
||||
serviceRegistry
|
||||
) );
|
||||
}
|
||||
|
||||
private void registerPredefinedGenerators() {
|
||||
register( "uuid2", UUIDGenerator.class );
|
||||
// can be done with UuidGenerator + strategy
|
||||
register( "guid", GUIDGenerator.class );
|
||||
|
@ -138,26 +148,30 @@ public class StandardIdentifierGeneratorFactory
|
|||
register( "foreign", ForeignGenerator.class );
|
||||
register( "enhanced-sequence", SequenceStyleGenerator.class );
|
||||
register( "enhanced-table", TableGenerator.class );
|
||||
}
|
||||
|
||||
private void registerUsingLegacyContributor() {
|
||||
final ConfigurationService configService = serviceRegistry.getService( ConfigurationService.class );
|
||||
final Object providerSetting = configService.getSettings().get( AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
|
||||
final Object providerSetting = configService.getSettings().get( IDENTIFIER_GENERATOR_STRATEGY_PROVIDER );
|
||||
if ( providerSetting != null ) {
|
||||
DeprecationLogger.DEPRECATION_LOGGER.deprecatedSetting2(
|
||||
AvailableSettings.IDENTIFIER_GENERATOR_STRATEGY_PROVIDER,
|
||||
IDENTIFIER_GENERATOR_STRATEGY_PROVIDER,
|
||||
"supply a org.hibernate.id.factory.spi.GenerationTypeStrategyRegistration Java service"
|
||||
);
|
||||
final IdentifierGeneratorStrategyProvider idGeneratorStrategyProvider =
|
||||
serviceRegistry.getService( StrategySelector.class )
|
||||
.resolveStrategy( IdentifierGeneratorStrategyProvider.class, providerSetting );
|
||||
for ( Map.Entry<String,Class<?>> entry : idGeneratorStrategyProvider.getStrategies().entrySet() ) {
|
||||
register( entry.getKey(), (Class) entry.getValue() );
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
Class<? extends IdentifierGenerator> generatorClass = (Class) entry.getValue();
|
||||
register( entry.getKey(), generatorClass );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void register(String strategy, Class<? extends IdentifierGenerator> generatorClass) {
|
||||
ID_GEN_FAC_LOGGER.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() );
|
||||
final Class previous = legacyGeneratorClassNameMap.put( strategy, generatorClass );
|
||||
final Class<?> previous = legacyGeneratorClassNameMap.put( strategy, generatorClass );
|
||||
if ( previous != null && ID_GEN_FAC_LOGGER.isDebugEnabled() ) {
|
||||
ID_GEN_FAC_LOGGER.debugf( " - overriding [%s]", previous.getName() );
|
||||
}
|
||||
|
@ -185,7 +199,7 @@ public class StandardIdentifierGeneratorFactory
|
|||
throw new NotYetImplementedFor6Exception( getClass() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override @Deprecated
|
||||
public Dialect getDialect() {
|
||||
if ( dialect == null ) {
|
||||
dialect = serviceRegistry.getService( JdbcEnvironment.class ).getDialect();
|
||||
|
@ -194,30 +208,28 @@ public class StandardIdentifierGeneratorFactory
|
|||
}
|
||||
|
||||
@Override
|
||||
public IdentifierGenerator createIdentifierGenerator(String strategy, Type type, Properties config) {
|
||||
public InMemoryGenerator createIdentifierGenerator(String strategy, Type type, Properties parameters) {
|
||||
try {
|
||||
final Class<? extends IdentifierGenerator> clazz = getIdentifierGeneratorClass( strategy );
|
||||
final IdentifierGenerator identifierGenerator;
|
||||
|
||||
final Class<? extends InMemoryGenerator> clazz = getIdentifierGeneratorClass( strategy );
|
||||
final InMemoryGenerator identifierGenerator;
|
||||
if ( beanContainer == null
|
||||
|| StandardGenerator.class.isAssignableFrom( clazz )
|
||||
|| legacyGeneratorClassNameMap.containsKey( strategy ) ) {
|
||||
identifierGenerator = clazz.newInstance();
|
||||
}
|
||||
else {
|
||||
final ContainedBean<? extends IdentifierGenerator> generatorBean = beanContainer.getBean(
|
||||
clazz,
|
||||
this,
|
||||
FallbackBeanInstanceProducer.INSTANCE
|
||||
);
|
||||
identifierGenerator = generatorBean.getBeanInstance();
|
||||
identifierGenerator =
|
||||
beanContainer.getBean( clazz, this, FallbackBeanInstanceProducer.INSTANCE )
|
||||
.getBeanInstance();
|
||||
}
|
||||
|
||||
identifierGenerator.configure( type, config, serviceRegistry );
|
||||
if ( identifierGenerator instanceof IdentifierGenerator ) {
|
||||
( (IdentifierGenerator) identifierGenerator ).configure( type, parameters, serviceRegistry );
|
||||
}
|
||||
return identifierGenerator;
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
final String entityName = config.getProperty( IdentifierGenerator.ENTITY_NAME );
|
||||
final String entityName = parameters.getProperty( IdentifierGenerator.ENTITY_NAME );
|
||||
throw new MappingException( String.format( "Could not instantiate id generator [entity-name=%s]", entityName ), e );
|
||||
}
|
||||
}
|
||||
|
@ -233,7 +245,7 @@ public class StandardIdentifierGeneratorFactory
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends IdentifierGenerator> getIdentifierGeneratorClass(String strategy) {
|
||||
public Class<? extends InMemoryGenerator> getIdentifierGeneratorClass(String strategy) {
|
||||
if ( "hilo".equals( strategy ) ) {
|
||||
throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" );
|
||||
}
|
||||
|
@ -242,16 +254,24 @@ public class StandardIdentifierGeneratorFactory
|
|||
: strategy;
|
||||
|
||||
Class<? extends IdentifierGenerator> generatorClass = legacyGeneratorClassNameMap.get( resolvedStrategy );
|
||||
if ( generatorClass == null ) {
|
||||
if ( generatorClass != null ) {
|
||||
return generatorClass;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return serviceRegistry.getService( ClassLoaderService.class ).classForName( resolvedStrategy );
|
||||
Class<? extends InMemoryGenerator> clazz =
|
||||
serviceRegistry.getService( ClassLoaderService.class )
|
||||
.classForName( resolvedStrategy );
|
||||
if ( !InMemoryGenerator.class.isAssignableFrom( clazz ) ) {
|
||||
// in principle, this shouldn't happen, since @GenericGenerator
|
||||
// constrains the type to subtypes of InMemoryGenerator
|
||||
throw new MappingException( clazz.getName() + " does not implement 'InMemoryGenerator'" );
|
||||
}
|
||||
return clazz;
|
||||
}
|
||||
catch ( ClassLoadingException e ) {
|
||||
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
return generatorClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@ import java.util.UUID;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||
import org.hibernate.id.factory.spi.CustomIdGeneratorCreationContext;
|
||||
import org.hibernate.id.factory.spi.StandardGenerator;
|
||||
import org.hibernate.tuple.GenerationTiming;
|
||||
import org.hibernate.tuple.InMemoryGenerator;
|
||||
import org.hibernate.type.descriptor.java.UUIDJavaType;
|
||||
import org.hibernate.type.descriptor.java.UUIDJavaType.ValueTransformer;
|
||||
|
||||
|
@ -24,7 +25,7 @@ import static org.hibernate.internal.util.ReflectHelper.getPropertyType;
|
|||
*
|
||||
* @see org.hibernate.annotations.UuidGenerator
|
||||
*/
|
||||
public class UuidGenerator implements StandardGenerator {
|
||||
public class UuidGenerator implements InMemoryGenerator {
|
||||
interface ValueGenerator {
|
||||
UUID generateUuid(SharedSessionContractImplementor session);
|
||||
}
|
||||
|
@ -59,7 +60,13 @@ public class UuidGenerator implements StandardGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
public Object generate(SharedSessionContractImplementor session, Object object) throws HibernateException {
|
||||
@Override
|
||||
public GenerationTiming getGenerationTiming() {
|
||||
return GenerationTiming.INSERT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object generate(SharedSessionContractImplementor session, Object owner, Object currentValue) {
|
||||
return valueTransformer.transform( generator.generateUuid( session ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public interface KeyValue extends Value {
|
|||
}
|
||||
|
||||
/**
|
||||
* We need to add {@code Column.isIdentity()}.
|
||||
* @deprecated We need to add {@code Column.isIdentity()}
|
||||
*/
|
||||
@Deprecated(since="6.2")
|
||||
boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect);
|
||||
|
|
|
@ -26,8 +26,10 @@ import java.io.Serializable;
|
|||
* statement. In this case, the generated value is retrieved from the database using a SQL
|
||||
* {@code select}.
|
||||
* </ul>
|
||||
* A generator may receive parameters from {@linkplain org.hibernate.annotations.ValueGenerationType
|
||||
* an annotation}. The generator may either:
|
||||
* Generically, a generator may be integrated with the program using the meta-annotation
|
||||
* {@link org.hibernate.annotations.ValueGenerationType}, which associates the generator with
|
||||
* a Java annotation type, called the <em>generator annotation</em>. A generator may receive
|
||||
* parameters from its generator annotation. The generator may either:
|
||||
* <ul>
|
||||
* <li>implement {@link AnnotationBasedGenerator}, and receive the annotation as an argument to
|
||||
* {@link AnnotationBasedGenerator#initialize},
|
||||
|
@ -35,14 +37,10 @@ import java.io.Serializable;
|
|||
* <li>declare a constructor which accepts just the annotation instance, or
|
||||
* <li>declare a only default constructor, in which case it will not receive parameters.
|
||||
* </ul>
|
||||
* On the other hand, there is some special machinery for configuring the much older interface
|
||||
* {@link org.hibernate.id.IdentifierGenerator}. But this machinery is only available for
|
||||
* identifier generation.
|
||||
*
|
||||
* @see org.hibernate.annotations.ValueGenerationType
|
||||
* @see org.hibernate.annotations.IdGeneratorType
|
||||
* @see org.hibernate.annotations.Generated
|
||||
* @see org.hibernate.annotations.GeneratorType
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Gavin King
|
||||
|
|
|
@ -10,15 +10,24 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
|||
|
||||
/**
|
||||
* A generator that is called to produce a value just before a row is written to the database.
|
||||
* The {@link #generate} method may execute arbitrary Java code, it may even, in principle,
|
||||
* access the database via JDBC. But however it is produced, the generated value is sent to the
|
||||
* The {@link #generate} method may execute arbitrary Java code. It may even, in principle,
|
||||
* access the database via JDBC. But however it's produced, the generated value is sent to the
|
||||
* database via a parameter of a JDBC prepared statement, just like any other field or property
|
||||
* value.
|
||||
* <p>
|
||||
* Any {@link InMemoryGenerator} may be used to produce {@linkplain jakarta.persistence.Id
|
||||
* Any {@link InMemoryGenerator} with {@linkplain #getGenerationTiming() generation timing}
|
||||
* {@link GenerationTiming#INSERT} may be used to produce {@linkplain jakarta.persistence.Id
|
||||
* identifiers}. The built-in identifier generators all implement the older extension point
|
||||
* {@link org.hibernate.id.IdentifierGenerator}, which is a subtype of this interface, but that
|
||||
* is no longer a requirement for custom id generators.
|
||||
* <p>
|
||||
* A custom id generator may be integrated with the program using either:
|
||||
* <ul>
|
||||
* <li>the meta-annotation {@link org.hibernate.annotations.IdGeneratorType} or
|
||||
* <li>the annotation {@link org.hibernate.annotations.GenericGenerator}.
|
||||
* </ul>
|
||||
* On the other hand, generators for regular fields and properties may be integrated using
|
||||
* {@link org.hibernate.annotations.ValueGenerationType}, as for any {@link Generator}.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue