clean up SequenceStyleGenerator + StandardOptimizerDescriptor
This commit is contained in:
parent
b682a1036c
commit
91eb9e1f20
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.id.enhanced;
|
||||
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class CustomOptimizerDescriptor implements OptimizerDescriptor {
|
||||
private final String className;
|
||||
|
||||
CustomOptimizerDescriptor(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
@Override
|
||||
public boolean isPooled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExternalName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Optimizer> getOptimizerClass() throws ClassNotFoundException {
|
||||
return ReflectHelper.classForName( className );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.id.enhanced;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public interface OptimizerDescriptor {
|
||||
boolean isPooled();
|
||||
String getExternalName();
|
||||
Class<? extends Optimizer> getOptimizerClass()
|
||||
throws ClassNotFoundException;
|
||||
}
|
|
@ -11,12 +11,11 @@ import java.util.Properties;
|
|||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.ReflectHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
|
||||
|
||||
/**
|
||||
* Factory for {@link Optimizer} instances.
|
||||
*
|
||||
|
@ -34,59 +33,54 @@ public class OptimizerFactory {
|
|||
* @param optimizerName The name of the optimizer
|
||||
*
|
||||
* @return {@code true} indicates the optimizer is a pooled strategy.
|
||||
*
|
||||
* @deprecated No longer used
|
||||
*/
|
||||
@Deprecated(since = "6.3")
|
||||
public static boolean isPooledOptimizer(String optimizerName) {
|
||||
final StandardOptimizerDescriptor standardDescriptor = StandardOptimizerDescriptor.fromExternalName( optimizerName );
|
||||
return standardDescriptor != null && standardDescriptor.isPooled();
|
||||
return StandardOptimizerDescriptor.fromExternalName( optimizerName ).isPooled();
|
||||
}
|
||||
|
||||
private static final Class[] CTOR_SIG = new Class[] { Class.class, int.class };
|
||||
private static final Class<?>[] CTOR_SIG = new Class[] { Class.class, int.class };
|
||||
|
||||
private static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
|
||||
private static Optimizer buildOptimizer(OptimizerDescriptor descriptor, Class<?> returnClass, int incrementSize) {
|
||||
final Class<? extends Optimizer> optimizerClass;
|
||||
|
||||
final StandardOptimizerDescriptor standardDescriptor = StandardOptimizerDescriptor.fromExternalName( type );
|
||||
if ( standardDescriptor != null ) {
|
||||
optimizerClass = standardDescriptor.getOptimizerClass();
|
||||
}
|
||||
else {
|
||||
try {
|
||||
optimizerClass = ReflectHelper.classForName( type );
|
||||
optimizerClass = descriptor.getOptimizerClass();
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
LOG.unableToLocateCustomOptimizerClass( type );
|
||||
catch ( Throwable ignore ) {
|
||||
LOG.unableToLocateCustomOptimizerClass( descriptor.getExternalName() );
|
||||
return buildFallbackOptimizer( returnClass, incrementSize );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final Constructor ctor = optimizerClass.getConstructor( CTOR_SIG );
|
||||
return (Optimizer) ctor.newInstance( returnClass, incrementSize );
|
||||
final Constructor<? extends Optimizer> ctor = optimizerClass.getConstructor( CTOR_SIG );
|
||||
return ctor.newInstance( returnClass, incrementSize );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
LOG.unableToInstantiateOptimizer( type );
|
||||
catch ( Throwable ignore ) {
|
||||
LOG.unableToInstantiateOptimizer( descriptor.getExternalName() );
|
||||
}
|
||||
|
||||
return buildFallbackOptimizer( returnClass, incrementSize );
|
||||
}
|
||||
|
||||
private static Optimizer buildFallbackOptimizer(Class returnClass, int incrementSize) {
|
||||
private static Optimizer buildFallbackOptimizer(Class<?> returnClass, int incrementSize) {
|
||||
return new NoopOptimizer( returnClass, incrementSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an optimizer
|
||||
*
|
||||
* @param type The optimizer type, either a short-hand name or the {@link Optimizer} class name.
|
||||
* @param type The optimizer type, either a shorthand name or the {@link Optimizer} class name.
|
||||
* @param returnClass The generated value java type
|
||||
* @param incrementSize The increment size.
|
||||
* @param explicitInitialValue The user supplied initial-value (-1 indicates the user did not specify).
|
||||
*
|
||||
* @return The built optimizer
|
||||
*/
|
||||
public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize, long explicitInitialValue) {
|
||||
public static Optimizer buildOptimizer(OptimizerDescriptor type, Class<?> returnClass, int incrementSize, long explicitInitialValue) {
|
||||
final Optimizer optimizer = buildOptimizer( type, returnClass, incrementSize );
|
||||
if ( InitialValueAwareOptimizer.class.isInstance( optimizer ) ) {
|
||||
if ( optimizer instanceof InitialValueAwareOptimizer ) {
|
||||
( (InitialValueAwareOptimizer) optimizer ).injectInitialValue( explicitInitialValue );
|
||||
}
|
||||
return optimizer;
|
||||
|
@ -99,16 +93,19 @@ public class OptimizerFactory {
|
|||
if ( incrementSize <= 1 ) {
|
||||
return StandardOptimizerDescriptor.NONE.getExternalName();
|
||||
}
|
||||
|
||||
else {
|
||||
// see if the user defined a preferred pooled optimizer...
|
||||
final String preferredPooledOptimizerStrategy = configSettings.getProperty( AvailableSettings.PREFERRED_POOLED_OPTIMIZER );
|
||||
if ( StringHelper.isNotEmpty( preferredPooledOptimizerStrategy ) ) {
|
||||
final String preferredPooledOptimizerStrategy =
|
||||
configSettings.getProperty( AvailableSettings.PREFERRED_POOLED_OPTIMIZER );
|
||||
if ( isNotEmpty( preferredPooledOptimizerStrategy ) ) {
|
||||
return preferredPooledOptimizerStrategy;
|
||||
}
|
||||
|
||||
else {
|
||||
// otherwise fallback to the fallback strategy
|
||||
return StandardOptimizerDescriptor.POOLED.getExternalName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private OptimizerFactory() {
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.hibernate.boot.model.naming.Identifier;
|
|||
import org.hibernate.boot.model.relational.Database;
|
||||
import org.hibernate.boot.model.relational.QualifiedName;
|
||||
import org.hibernate.boot.model.relational.QualifiedNameParser;
|
||||
import org.hibernate.boot.model.relational.QualifiedSequenceName;
|
||||
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
|
||||
import org.hibernate.boot.registry.selector.spi.StrategySelector;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
|
@ -28,7 +29,6 @@ import org.hibernate.id.PersistentIdentifierGenerator;
|
|||
import org.hibernate.id.SequenceMismatchStrategy;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
import org.hibernate.type.Type;
|
||||
|
@ -36,8 +36,12 @@ import org.hibernate.type.Type;
|
|||
import org.jboss.logging.Logger;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY;
|
||||
import static org.hibernate.id.enhanced.OptimizerFactory.determineImplicitOptimizerName;
|
||||
import static org.hibernate.internal.log.IncubationLogger.INCUBATION_LOGGER;
|
||||
import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues;
|
||||
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
|
||||
import static org.hibernate.internal.util.config.ConfigurationHelper.getInt;
|
||||
import static org.hibernate.internal.util.config.ConfigurationHelper.getString;
|
||||
|
||||
/**
|
||||
* Generates identifier values based on a sequence-style database structure.
|
||||
|
@ -188,65 +192,33 @@ public class SequenceStyleGenerator
|
|||
@Override
|
||||
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, parameters, false );
|
||||
|
||||
final QualifiedName sequenceName = determineSequenceName( parameters, dialect, jdbcEnvironment, serviceRegistry );
|
||||
|
||||
final int initialValue = determineInitialValue( parameters );
|
||||
int incrementSize = determineIncrementSize( parameters );
|
||||
final OptimizerDescriptor optimizationStrategy = determineOptimizationStrategy( parameters, incrementSize );
|
||||
|
||||
final String optimizationStrategy = determineOptimizationStrategy(parameters, incrementSize );
|
||||
boolean forceTableUse = getBoolean( FORCE_TBL_PARAM, parameters, false );
|
||||
final boolean physicalSequence = isPhysicalSequence( jdbcEnvironment, forceTableUse );
|
||||
|
||||
final boolean isPooledOptimizer = OptimizerFactory.isPooledOptimizer( optimizationStrategy );
|
||||
|
||||
|
||||
SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
|
||||
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
|
||||
SequenceMismatchStrategy::interpret,
|
||||
SequenceMismatchStrategy.EXCEPTION
|
||||
incrementSize = adjustIncrementSize(
|
||||
jdbcEnvironment,
|
||||
sequenceName,
|
||||
incrementSize,
|
||||
physicalSequence,
|
||||
optimizationStrategy,
|
||||
serviceRegistry
|
||||
);
|
||||
|
||||
if ( sequenceMismatchStrategy != SequenceMismatchStrategy.NONE
|
||||
&& isPooledOptimizer
|
||||
&& isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
|
||||
String databaseSequenceName = sequenceName.getObjectName().getText();
|
||||
Number databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
|
||||
|
||||
if ( databaseIncrementValue != null && databaseIncrementValue.intValue() != incrementSize ) {
|
||||
int dbIncrementValue = databaseIncrementValue.intValue();
|
||||
|
||||
switch ( sequenceMismatchStrategy ) {
|
||||
case EXCEPTION:
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"The increment size of the [%s] sequence is set to [%d] in the entity mapping " +
|
||||
"while the associated database sequence increment size is [%d].",
|
||||
databaseSequenceName, incrementSize, dbIncrementValue
|
||||
)
|
||||
);
|
||||
case FIX:
|
||||
incrementSize = dbIncrementValue;
|
||||
case LOG:
|
||||
LOG.sequenceIncrementSizeMismatch( databaseSequenceName, incrementSize, dbIncrementValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
incrementSize = determineAdjustedIncrementSize( optimizationStrategy, incrementSize );
|
||||
|
||||
if ( dialect.getSequenceSupport().supportsSequences() && !forceTableUse ) {
|
||||
if ( !dialect.getSequenceSupport().supportsPooledSequences()
|
||||
&& OptimizerFactory.isPooledOptimizer( optimizationStrategy ) ) {
|
||||
if ( physicalSequence
|
||||
&& optimizationStrategy.isPooled()
|
||||
&& !dialect.getSequenceSupport().supportsPooledSequences() ) {
|
||||
forceTableUse = true;
|
||||
LOG.forcingTableUse();
|
||||
}
|
||||
}
|
||||
|
||||
this.databaseStructure = buildDatabaseStructure(
|
||||
type,
|
||||
|
@ -261,11 +233,53 @@ public class SequenceStyleGenerator
|
|||
optimizationStrategy,
|
||||
identifierType.getReturnedClass(),
|
||||
incrementSize,
|
||||
ConfigurationHelper.getInt( INITIAL_PARAM, parameters, -1 )
|
||||
getInt( INITIAL_PARAM, parameters, -1 )
|
||||
);
|
||||
this.databaseStructure.configure( optimizer );
|
||||
}
|
||||
|
||||
private int adjustIncrementSize(
|
||||
JdbcEnvironment jdbcEnvironment,
|
||||
QualifiedName sequenceName,
|
||||
int incrementSize,
|
||||
boolean physicalSequence,
|
||||
OptimizerDescriptor optimizationStrategy,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
final SequenceMismatchStrategy sequenceMismatchStrategy = configurationService.getSetting(
|
||||
AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY,
|
||||
SequenceMismatchStrategy::interpret,
|
||||
SequenceMismatchStrategy.EXCEPTION
|
||||
);
|
||||
|
||||
if ( sequenceMismatchStrategy != SequenceMismatchStrategy.NONE
|
||||
&& optimizationStrategy.isPooled()
|
||||
&& physicalSequence ) {
|
||||
final String databaseSequenceName = sequenceName.getObjectName().getText();
|
||||
final Number databaseIncrementValue = getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
|
||||
if ( databaseIncrementValue != null && databaseIncrementValue.intValue() != incrementSize) {
|
||||
final int dbIncrementValue = databaseIncrementValue.intValue();
|
||||
switch ( sequenceMismatchStrategy ) {
|
||||
case EXCEPTION:
|
||||
throw new MappingException(
|
||||
String.format(
|
||||
"The increment size of the [%s] sequence is set to [%d] in the entity mapping "
|
||||
+ "while the associated database sequence increment size is [%d].",
|
||||
databaseSequenceName, incrementSize, dbIncrementValue
|
||||
)
|
||||
);
|
||||
case FIX:
|
||||
incrementSize = dbIncrementValue;
|
||||
case LOG:
|
||||
//TODO: the log message is correct for the case of FIX, but wrong for LOG
|
||||
LOG.sequenceIncrementSizeMismatch( databaseSequenceName, incrementSize, dbIncrementValue );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return determineAdjustedIncrementSize( optimizationStrategy, incrementSize );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerExportables(Database database) {
|
||||
databaseStructure.registerExportables( database );
|
||||
|
@ -294,16 +308,16 @@ public class SequenceStyleGenerator
|
|||
JdbcEnvironment jdbcEnv,
|
||||
ServiceRegistry serviceRegistry) {
|
||||
final Identifier catalog = jdbcEnv.getIdentifierHelper().toIdentifier(
|
||||
ConfigurationHelper.getString( CATALOG, params )
|
||||
getString( CATALOG, params )
|
||||
);
|
||||
final Identifier schema = jdbcEnv.getIdentifierHelper().toIdentifier(
|
||||
ConfigurationHelper.getString( SCHEMA, params )
|
||||
getString( SCHEMA, params )
|
||||
);
|
||||
|
||||
final String sequenceName = ConfigurationHelper.getString(
|
||||
final String sequenceName = getString(
|
||||
SEQUENCE_PARAM,
|
||||
params,
|
||||
() -> ConfigurationHelper.getString( ALT_SEQUENCE_PARAM, params )
|
||||
() -> getString( ALT_SEQUENCE_PARAM, params )
|
||||
);
|
||||
|
||||
if ( StringHelper.isNotEmpty( sequenceName ) ) {
|
||||
|
@ -333,7 +347,7 @@ public class SequenceStyleGenerator
|
|||
|
||||
final String namingStrategySetting = coalesceSuppliedValues(
|
||||
() -> {
|
||||
final String localSetting = ConfigurationHelper.getString( ID_DB_STRUCTURE_NAMING_STRATEGY, params );
|
||||
final String localSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, params );
|
||||
if ( localSetting != null ) {
|
||||
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
|
||||
}
|
||||
|
@ -341,7 +355,7 @@ public class SequenceStyleGenerator
|
|||
},
|
||||
() -> {
|
||||
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
final String globalSetting = ConfigurationHelper.getString( ID_DB_STRUCTURE_NAMING_STRATEGY, configurationService.getSettings() );
|
||||
final String globalSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, configurationService.getSettings() );
|
||||
if ( globalSetting != null ) {
|
||||
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
|
||||
}
|
||||
|
@ -370,7 +384,7 @@ public class SequenceStyleGenerator
|
|||
* @return The value column name
|
||||
*/
|
||||
protected Identifier determineValueColumnName(Properties params, JdbcEnvironment jdbcEnvironment) {
|
||||
final String name = ConfigurationHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
|
||||
final String name = getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
|
||||
return jdbcEnvironment.getIdentifierHelper().toIdentifier( name );
|
||||
}
|
||||
|
||||
|
@ -385,7 +399,7 @@ public class SequenceStyleGenerator
|
|||
* @return The initial value
|
||||
*/
|
||||
protected int determineInitialValue(Properties params) {
|
||||
return ConfigurationHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
|
||||
return getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -398,7 +412,7 @@ public class SequenceStyleGenerator
|
|||
* @return The increment size
|
||||
*/
|
||||
protected int determineIncrementSize(Properties params) {
|
||||
return ConfigurationHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
|
||||
return getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -410,11 +424,9 @@ public class SequenceStyleGenerator
|
|||
* @param incrementSize The {@link #determineIncrementSize determined increment size}
|
||||
* @return The optimizer strategy (name)
|
||||
*/
|
||||
protected String determineOptimizationStrategy(Properties params, int incrementSize) {
|
||||
return ConfigurationHelper.getString(
|
||||
OPT_PARAM,
|
||||
params,
|
||||
OptimizerFactory.determineImplicitOptimizerName( incrementSize, params )
|
||||
protected OptimizerDescriptor determineOptimizationStrategy(Properties params, int incrementSize) {
|
||||
return StandardOptimizerDescriptor.fromExternalName(
|
||||
getString( OPT_PARAM, params, determineImplicitOptimizerName( incrementSize, params ) )
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -426,36 +438,35 @@ public class SequenceStyleGenerator
|
|||
* @param incrementSize The {@link #determineIncrementSize determined increment size}
|
||||
* @return The adjusted increment size.
|
||||
*/
|
||||
protected int determineAdjustedIncrementSize(String optimizationStrategy, int incrementSize) {
|
||||
final int resolvedIncrementSize;
|
||||
if ( Math.abs( incrementSize ) > 1 &&
|
||||
StandardOptimizerDescriptor.NONE.getExternalName().equals( optimizationStrategy ) ) {
|
||||
protected int determineAdjustedIncrementSize(OptimizerDescriptor optimizationStrategy, int incrementSize) {
|
||||
if ( optimizationStrategy == StandardOptimizerDescriptor.NONE ) {
|
||||
if ( incrementSize < -1 ) {
|
||||
resolvedIncrementSize = -1;
|
||||
LOG.honoringOptimizerSetting(
|
||||
StandardOptimizerDescriptor.NONE.getExternalName(),
|
||||
INCREMENT_PARAM,
|
||||
incrementSize,
|
||||
"negative",
|
||||
resolvedIncrementSize
|
||||
-1
|
||||
);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// incrementSize > 1
|
||||
resolvedIncrementSize = 1;
|
||||
else if ( incrementSize > 1 ) {
|
||||
LOG.honoringOptimizerSetting(
|
||||
StandardOptimizerDescriptor.NONE.getExternalName(),
|
||||
INCREMENT_PARAM,
|
||||
incrementSize,
|
||||
"positive",
|
||||
resolvedIncrementSize
|
||||
1
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return incrementSize;
|
||||
}
|
||||
}
|
||||
else {
|
||||
resolvedIncrementSize = incrementSize;
|
||||
return incrementSize;
|
||||
}
|
||||
return resolvedIncrementSize;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -571,11 +582,12 @@ public class SequenceStyleGenerator
|
|||
.stream()
|
||||
.filter(
|
||||
sequenceInformation -> {
|
||||
Identifier catalog = sequenceInformation.getSequenceName().getCatalogName();
|
||||
Identifier schema = sequenceInformation.getSequenceName().getSchemaName();
|
||||
return sequenceName.equalsIgnoreCase( sequenceInformation.getSequenceName().getSequenceName().getText() ) &&
|
||||
( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) ) &&
|
||||
( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
|
||||
QualifiedSequenceName name = sequenceInformation.getSequenceName();
|
||||
Identifier catalog = name.getCatalogName();
|
||||
Identifier schema = name.getSchemaName();
|
||||
return sequenceName.equalsIgnoreCase( name.getSequenceName().getText() )
|
||||
&& ( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) )
|
||||
&& ( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
|
||||
}
|
||||
)
|
||||
.map( SequenceInformation::getIncrementValue )
|
||||
|
|
|
@ -6,72 +6,97 @@
|
|||
*/
|
||||
package org.hibernate.id.enhanced;
|
||||
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.AssertionFailure;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
import static org.hibernate.internal.util.StringHelper.isEmpty;
|
||||
|
||||
/**
|
||||
* Enumeration of the standard Hibernate id generation optimizers.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public enum StandardOptimizerDescriptor {
|
||||
public enum StandardOptimizerDescriptor implements OptimizerDescriptor {
|
||||
/**
|
||||
* Describes the optimizer for no optimization.
|
||||
*/
|
||||
NONE( "none", NoopOptimizer.class ),
|
||||
NONE,
|
||||
/**
|
||||
* Describes the optimizer for using a custom "hilo" algorithm optimization.
|
||||
*/
|
||||
HILO( "hilo", HiLoOptimizer.class ),
|
||||
HILO,
|
||||
/**
|
||||
* Describes the optimizer for using a custom "hilo" algorithm optimization, following the
|
||||
* legacy Hibernate hilo algorithm.
|
||||
*/
|
||||
LEGACY_HILO( "legacy-hilo", LegacyHiLoAlgorithmOptimizer.class ),
|
||||
LEGACY_HILO,
|
||||
/**
|
||||
* Describes the optimizer for use with tables/sequences that store the chunk information.
|
||||
* Here, specifically the hi value is stored in the database.
|
||||
*/
|
||||
POOLED( "pooled", PooledOptimizer.class, true ),
|
||||
POOLED,
|
||||
/**
|
||||
* Describes the optimizer for use with tables/sequences that store the chunk information.
|
||||
* Here, specifically the lo value is stored in the database.
|
||||
*/
|
||||
POOLED_LO( "pooled-lo", PooledLoOptimizer.class, true ),
|
||||
POOLED_LO,
|
||||
/**
|
||||
* Describes the optimizer for use with tables/sequences that store the chunk information.
|
||||
* Here, specifically the lo value is stored in the database and ThreadLocal used to cache
|
||||
* the generation state.
|
||||
*/
|
||||
POOLED_LOTL( "pooled-lotl", PooledLoThreadLocalOptimizer.class, true );
|
||||
|
||||
private static final Logger log = Logger.getLogger( StandardOptimizerDescriptor.class );
|
||||
|
||||
private final String externalName;
|
||||
private final Class<? extends Optimizer> optimizerClass;
|
||||
private final boolean isPooled;
|
||||
|
||||
StandardOptimizerDescriptor(String externalName, Class<? extends Optimizer> optimizerClass) {
|
||||
this( externalName, optimizerClass, false );
|
||||
}
|
||||
|
||||
StandardOptimizerDescriptor(String externalName, Class<? extends Optimizer> optimizerClass, boolean pooled) {
|
||||
this.externalName = externalName;
|
||||
this.optimizerClass = optimizerClass;
|
||||
this.isPooled = pooled;
|
||||
}
|
||||
POOLED_LOTL;
|
||||
|
||||
@Override
|
||||
public String getExternalName() {
|
||||
return externalName;
|
||||
switch ( this ) {
|
||||
case NONE:
|
||||
return "none";
|
||||
case HILO:
|
||||
return "hilo";
|
||||
case LEGACY_HILO:
|
||||
return "legacy-hilo";
|
||||
case POOLED:
|
||||
return "pooled";
|
||||
case POOLED_LO:
|
||||
return "pooled-lo";
|
||||
case POOLED_LOTL:
|
||||
return "pooled-lotl";
|
||||
}
|
||||
throw new AssertionFailure( "unknown StandardOptimizerDescriptor" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Optimizer> getOptimizerClass() {
|
||||
return optimizerClass;
|
||||
switch ( this ) {
|
||||
case NONE:
|
||||
return NoopOptimizer.class;
|
||||
case HILO:
|
||||
return HiLoOptimizer.class;
|
||||
case LEGACY_HILO:
|
||||
return LegacyHiLoAlgorithmOptimizer.class;
|
||||
case POOLED:
|
||||
return PooledOptimizer.class;
|
||||
case POOLED_LO:
|
||||
return PooledLoOptimizer.class;
|
||||
case POOLED_LOTL:
|
||||
return PooledLoThreadLocalOptimizer.class;
|
||||
}
|
||||
throw new AssertionFailure( "unknown StandardOptimizerDescriptor" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPooled() {
|
||||
return isPooled;
|
||||
switch ( this ) {
|
||||
case NONE:
|
||||
case HILO:
|
||||
case LEGACY_HILO:
|
||||
return false;
|
||||
case POOLED:
|
||||
case POOLED_LO:
|
||||
case POOLED_LOTL:
|
||||
return true;
|
||||
}
|
||||
throw new AssertionFailure( "unknown StandardOptimizerDescriptor" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,32 +108,17 @@ public enum StandardOptimizerDescriptor {
|
|||
* {@link #NONE} is returned; if an unrecognized external name is supplied,
|
||||
* {@code null} is returned
|
||||
*/
|
||||
public static StandardOptimizerDescriptor fromExternalName(String externalName) {
|
||||
if ( StringHelper.isEmpty( externalName ) ) {
|
||||
log.debug( "No optimizer specified, using NONE as default" );
|
||||
public static OptimizerDescriptor fromExternalName(String externalName) {
|
||||
if ( isEmpty( externalName ) ) {
|
||||
return NONE;
|
||||
}
|
||||
else if ( NONE.externalName.equals( externalName ) ) {
|
||||
return NONE;
|
||||
}
|
||||
else if ( HILO.externalName.equals( externalName ) ) {
|
||||
return HILO;
|
||||
}
|
||||
else if ( LEGACY_HILO.externalName.equals( externalName ) ) {
|
||||
return LEGACY_HILO;
|
||||
}
|
||||
else if ( POOLED.externalName.equals( externalName ) ) {
|
||||
return POOLED;
|
||||
}
|
||||
else if ( POOLED_LO.externalName.equals( externalName ) ) {
|
||||
return POOLED_LO;
|
||||
}
|
||||
else if ( POOLED_LOTL.externalName.equals( externalName ) ) {
|
||||
return POOLED_LOTL;
|
||||
}
|
||||
else {
|
||||
log.debugf( "Unknown optimizer key [%s]; returning null assuming Optimizer impl class name", externalName );
|
||||
return null;
|
||||
for ( StandardOptimizerDescriptor value: values() ) {
|
||||
if ( value.getExternalName().equals( externalName ) ) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return new CustomOptimizerDescriptor( externalName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ import java.sql.PreparedStatement;
|
|||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
|
@ -53,7 +52,9 @@ import org.hibernate.type.Type;
|
|||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.hibernate.cfg.AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY;
|
||||
import static org.hibernate.id.enhanced.OptimizerFactory.determineImplicitOptimizerName;
|
||||
import static org.hibernate.internal.log.IncubationLogger.INCUBATION_LOGGER;
|
||||
import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues;
|
||||
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
|
||||
|
@ -336,27 +337,21 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
|
||||
final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
|
||||
|
||||
qualifiedTableName = determineGeneratorTableName(parameters, jdbcEnvironment, serviceRegistry );
|
||||
segmentColumnName = determineSegmentColumnName(parameters, jdbcEnvironment );
|
||||
valueColumnName = determineValueColumnName(parameters, jdbcEnvironment );
|
||||
qualifiedTableName = determineGeneratorTableName( parameters, jdbcEnvironment, serviceRegistry );
|
||||
segmentColumnName = determineSegmentColumnName( parameters, jdbcEnvironment );
|
||||
valueColumnName = determineValueColumnName( parameters, jdbcEnvironment );
|
||||
|
||||
segmentValue = determineSegmentValue(parameters);
|
||||
segmentValue = determineSegmentValue( parameters );
|
||||
|
||||
segmentValueLength = determineSegmentColumnSize(parameters);
|
||||
initialValue = determineInitialValue(parameters);
|
||||
incrementSize = determineIncrementSize(parameters);
|
||||
segmentValueLength = determineSegmentColumnSize( parameters );
|
||||
initialValue = determineInitialValue( parameters );
|
||||
incrementSize = determineIncrementSize( parameters );
|
||||
|
||||
final String optimizationStrategy = getString(
|
||||
OPT_PARAM,
|
||||
parameters,
|
||||
OptimizerFactory.determineImplicitOptimizerName( incrementSize, parameters)
|
||||
);
|
||||
int optimizerInitialValue = getInt( INITIAL_PARAM, parameters, -1 );
|
||||
optimizer = OptimizerFactory.buildOptimizer(
|
||||
optimizationStrategy,
|
||||
determineOptimizationStrategy( parameters, incrementSize ),
|
||||
identifierType.getReturnedClass(),
|
||||
incrementSize,
|
||||
optimizerInitialValue
|
||||
getInt( INITIAL_PARAM, parameters, -1 )
|
||||
);
|
||||
|
||||
contributor = parameters.getProperty( CONTRIBUTOR_NAME );
|
||||
|
@ -365,6 +360,12 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
private static OptimizerDescriptor determineOptimizationStrategy(Properties parameters, int incrementSize) {
|
||||
return StandardOptimizerDescriptor.fromExternalName(
|
||||
getString( OPT_PARAM, parameters, determineImplicitOptimizerName( incrementSize, parameters ) )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the table name to use for the generator values.
|
||||
* <p>
|
||||
|
@ -515,7 +516,6 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
return getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected String buildSelectQuery(String formattedPhysicalTableName, SqlStringGenerationContext context) {
|
||||
final String alias = "tbl";
|
||||
final String query = "select " + StringHelper.qualify( alias, valueColumnName )
|
||||
|
@ -523,7 +523,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
|
|||
+ " where " + StringHelper.qualify( alias, segmentColumnName ) + "=?";
|
||||
final LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
|
||||
lockOptions.setAliasSpecificLockMode( alias, LockMode.PESSIMISTIC_WRITE );
|
||||
final Map updateTargetColumnsMap = Collections.singletonMap( alias, new String[] { valueColumnName } );
|
||||
final Map<String,String[]> updateTargetColumnsMap = singletonMap( alias, new String[] { valueColumnName } );
|
||||
return context.getDialect().applyLocksToSql( query, lockOptions, updateTargetColumnsMap );
|
||||
}
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ public class OptimizerConcurrencyUnitTest extends BaseUnitTestCase {
|
|||
}
|
||||
|
||||
private Optimizer buildOptimizer(long initial, int increment) {
|
||||
return OptimizerFactory.buildOptimizer( optimizerDescriptor.getExternalName(), Long.class, increment, initial );
|
||||
return OptimizerFactory.buildOptimizer( optimizerDescriptor, Long.class, increment, initial );
|
||||
}
|
||||
|
||||
private <R> R getDoneFutureValue(Future<R> future) {
|
||||
|
|
|
@ -328,7 +328,7 @@ public class OptimizerUnitTest {
|
|||
StandardOptimizerDescriptor descriptor,
|
||||
long initial,
|
||||
int increment) {
|
||||
return OptimizerFactory.buildOptimizer( descriptor.getExternalName(), Long.class, increment, initial );
|
||||
return OptimizerFactory.buildOptimizer( descriptor, Long.class, increment, initial );
|
||||
}
|
||||
|
||||
private static class SourceMock implements AccessCallback {
|
||||
|
|
Loading…
Reference in New Issue