code cleanups to SequenceStyleGenerator and TableGenerator (#8816)

* code cleanups to SequenceStyleGenerator and TableGenerator

Signed-off-by: Gavin King <gavin@hibernate.org>

* code cleanups to TableStructure and SequenceStructure

Signed-off-by: Gavin King <gavin@hibernate.org>

* more very minor cleanups around enhanced generators

Signed-off-by: Gavin King <gavin@hibernate.org>

* more very minor cleanups around enhanced generators

Signed-off-by: Gavin King <gavin@hibernate.org>

* more very minor cleanups around enhanced generators

Signed-off-by: Gavin King <gavin@hibernate.org>

---------

Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
Gavin King 2024-08-22 19:22:59 +02:00 committed by GitHub
parent b3eea24e0c
commit 5dcbdf64f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 208 additions and 258 deletions

View File

@ -14,17 +14,27 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Objects;
import java.util.Properties;
import org.hibernate.Internal;
import org.hibernate.TransientObjectException;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.enhanced.ImplicitDatabaseObjectNamingStrategy;
import org.hibernate.id.enhanced.StandardNamingStrategy;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import static org.hibernate.cfg.MappingSettings.ID_DB_STRUCTURE_NAMING_STRATEGY;
import static org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved;
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.getString;
import static org.hibernate.spi.NavigablePath.IDENTIFIER_MAPPER_PROPERTY;
/**
@ -625,6 +635,31 @@ public final class IdentifierGeneratorHelper {
}
}
public static ImplicitDatabaseObjectNamingStrategy getNamingStrategy(Properties params, ServiceRegistry serviceRegistry) {
final StrategySelector strategySelector = serviceRegistry.requireService( StrategySelector.class );
final String namingStrategySetting = coalesceSuppliedValues(
() -> {
final String localSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, params );
if ( localSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return localSetting;
},
() -> {
final ConfigurationService configurationService = serviceRegistry.requireService( ConfigurationService.class );
final String globalSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, configurationService.getSettings() );
if ( globalSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return globalSetting;
},
StandardNamingStrategy.class::getName
);
return strategySelector.resolveStrategy( ImplicitDatabaseObjectNamingStrategy.class, namingStrategySetting );
}
/**
* Disallow instantiation of IdentifierGeneratorHelper.
*/

View File

@ -27,8 +27,8 @@ public interface Optimizer {
/**
* Generate an identifier value accounting for this specific optimization.
*
* All known implementors are synchronized. Consider carefully if a new
* implementation could drop this requirement.
* @implNote All known implementors are synchronized. Consider carefully
* if a new implementation could drop this requirement.
*
* @param callback Callback to access the underlying value source.
* @return The generated identifier value.

View File

@ -16,14 +16,15 @@ import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedName;
import org.hibernate.boot.model.relational.Sequence;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.internal.CoreMessageLogger;
import org.jboss.logging.Logger;
import static org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder;
/**
* Describes a sequence.
*
@ -39,7 +40,7 @@ public class SequenceStructure implements DatabaseStructure {
private final QualifiedName logicalQualifiedSequenceName;
private final int initialValue;
private final int incrementSize;
private final Class numberType;
private final Class<?> numberType;
private final String options;
private String sql;
@ -48,12 +49,11 @@ public class SequenceStructure implements DatabaseStructure {
protected QualifiedName physicalSequenceName;
public SequenceStructure(
JdbcEnvironment jdbcEnvironment,
String contributor,
QualifiedName qualifiedSequenceName,
int initialValue,
int incrementSize,
Class numberType) {
Class<?> numberType) {
this.contributor = contributor;
this.logicalQualifiedSequenceName = qualifiedSequenceName;
@ -64,13 +64,12 @@ public class SequenceStructure implements DatabaseStructure {
}
public SequenceStructure(
JdbcEnvironment jdbcEnvironment,
String contributor,
QualifiedName qualifiedSequenceName,
int initialValue,
int incrementSize,
String options,
Class numberType) {
Class<?> numberType) {
this.contributor = contributor;
this.logicalQualifiedSequenceName = qualifiedSequenceName;
@ -100,7 +99,7 @@ public class SequenceStructure implements DatabaseStructure {
return initialValue;
}
@Override
@Override @Deprecated
public String[] getAllSqlForTests() {
return new String[] { sql };
}
@ -116,12 +115,13 @@ public class SequenceStructure implements DatabaseStructure {
public IntegralDataTypeHolder getNextValue() {
accessCounter++;
try {
final PreparedStatement st = session.getJdbcCoordinator().getStatementPreparer().prepareStatement( sql );
final JdbcCoordinator jdbcCoordinator = session.getJdbcCoordinator();
final PreparedStatement st = jdbcCoordinator.getStatementPreparer().prepareStatement( sql );
try {
final ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( st, sql );
final ResultSet rs = jdbcCoordinator.getResultSetReturn().extract( st, sql );
try {
rs.next();
final IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
final IntegralDataTypeHolder value = getIntegralDataTypeHolder( numberType );
value.initialize( rs, 1 );
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Sequence value obtained: %s", value.makeValue() );
@ -130,7 +130,7 @@ public class SequenceStructure implements DatabaseStructure {
}
finally {
try {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( rs, st );
jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( rs, st );
}
catch( Throwable ignore ) {
// intentionally empty
@ -138,8 +138,8 @@ public class SequenceStructure implements DatabaseStructure {
}
}
finally {
session.getJdbcCoordinator().getLogicalConnection().getResourceRegistry().release( st );
session.getJdbcCoordinator().afterStatementExecution();
jdbcCoordinator.getLogicalConnection().getResourceRegistry().release( st );
jdbcCoordinator.afterStatementExecution();
}
}
@ -171,7 +171,8 @@ public class SequenceStructure implements DatabaseStructure {
@Override
public void initialize(SqlStringGenerationContext context) {
this.sql = context.getDialect().getSequenceSupport().getSequenceNextValString( context.format( physicalSequenceName ) );
this.sql = context.getDialect().getSequenceSupport()
.getSequenceNextValString( context.format( physicalSequenceName ) );
}
@Override
@ -213,6 +214,6 @@ public class SequenceStructure implements DatabaseStructure {
);
}
this.physicalSequenceName = sequence.getName();
physicalSequenceName = sequence.getName();
}
}

View File

@ -6,9 +6,7 @@
*/
package org.hibernate.id.enhanced;
import java.util.Collections;
import java.util.Iterator;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
@ -20,7 +18,6 @@ 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;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.config.spi.ConfigurationService;
@ -32,7 +29,6 @@ import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.id.SequenceMismatchStrategy;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tool.schema.Action;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
@ -41,10 +37,10 @@ import org.hibernate.type.Type;
import org.jboss.logging.Logger;
import static org.hibernate.cfg.AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY;
import static java.util.Collections.singleton;
import static org.hibernate.id.IdentifierGeneratorHelper.getNamingStrategy;
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.StringHelper.isNotEmpty;
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;
@ -201,7 +197,7 @@ public class SequenceStyleGenerator
final JdbcEnvironment jdbcEnvironment = serviceRegistry.requireService( JdbcEnvironment.class );
final Dialect dialect = jdbcEnvironment.getDialect();
this.identifierType = type;
identifierType = type;
final QualifiedName sequenceName = determineSequenceName( parameters, dialect, jdbcEnvironment, serviceRegistry );
final int initialValue = determineInitialValue( parameters );
@ -228,7 +224,7 @@ public class SequenceStyleGenerator
LOG.forcingTableUse();
}
this.databaseStructure = buildDatabaseStructure(
databaseStructure = buildDatabaseStructure(
type,
parameters,
jdbcEnvironment,
@ -237,15 +233,15 @@ public class SequenceStyleGenerator
initialValue,
incrementSize
);
this.optimizer = OptimizerFactory.buildOptimizer(
optimizer = OptimizerFactory.buildOptimizer(
optimizationStrategy,
identifierType.getReturnedClass(),
incrementSize,
getInt( INITIAL_PARAM, parameters, -1 )
);
this.databaseStructure.configure( optimizer );
databaseStructure.configure( optimizer );
this.options = parameters.getProperty( OPTIONS );
options = parameters.getProperty( OPTIONS );
}
private int adjustIncrementSize(
@ -267,7 +263,9 @@ public class SequenceStyleGenerator
&& optimizationStrategy.isPooled()
&& physicalSequence ) {
final String databaseSequenceName = sequenceName.getObjectName().getText();
final Number databaseIncrementValue = isSchemaToBeRecreated( contributor, configurationService ) ? null : getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
final Number databaseIncrementValue =
isSchemaToBeRecreated( contributor, configurationService ) ? null
: getSequenceIncrementValue( jdbcEnvironment, databaseSequenceName );
if ( databaseIncrementValue != null && databaseIncrementValue.intValue() != incrementSize) {
final int dbIncrementValue = databaseIncrementValue.intValue();
switch ( sequenceMismatchStrategy ) {
@ -292,7 +290,8 @@ public class SequenceStyleGenerator
}
private boolean isSchemaToBeRecreated(String contributor, ConfigurationService configurationService) {
final Set<ActionGrouping> actions = ActionGrouping.interpret( Collections.singleton(contributor), configurationService.getSettings() );
final Set<ActionGrouping> actions =
ActionGrouping.interpret( singleton( contributor ), configurationService.getSettings() );
// We know this will only contain at most 1 action
final Iterator<ActionGrouping> it = actions.iterator();
final Action dbAction = it.hasNext() ? it.next().getDatabaseAction() : null;
@ -306,7 +305,7 @@ public class SequenceStyleGenerator
@Override
public void initialize(SqlStringGenerationContext context) {
this.databaseStructure.initialize( context );
databaseStructure.initialize( context );
}
/**
@ -327,62 +326,32 @@ public class SequenceStyleGenerator
JdbcEnvironment jdbcEnv,
ServiceRegistry serviceRegistry) {
final IdentifierHelper identifierHelper = jdbcEnv.getIdentifierHelper();
final Identifier catalog = identifierHelper.toIdentifier( getString( CATALOG, params ) );
final Identifier schema = identifierHelper.toIdentifier( getString( SCHEMA, params ) );
final String sequenceName = getString( SEQUENCE_PARAM, params, () -> getString( ALT_SEQUENCE_PARAM, params ) );
if ( StringHelper.isNotEmpty( sequenceName ) ) {
return sequenceName( params, serviceRegistry, sequenceName, catalog, schema, identifierHelper );
}
private static QualifiedName sequenceName(
Properties params,
ServiceRegistry serviceRegistry,
String explicitSequenceName,
Identifier catalog, Identifier schema,
IdentifierHelper identifierHelper) {
if ( isNotEmpty( explicitSequenceName ) ) {
// we have an explicit name, use it
if ( sequenceName.contains( "." ) ) {
return QualifiedNameParser.INSTANCE.parse( sequenceName );
return explicitSequenceName.contains(".")
? QualifiedNameParser.INSTANCE.parse( explicitSequenceName )
: new QualifiedNameParser.NameParts( catalog, schema,
identifierHelper.toIdentifier( explicitSequenceName ) );
}
else {
return new QualifiedNameParser.NameParts(
catalog,
schema,
identifierHelper.toIdentifier( sequenceName )
);
}
}
// otherwise, determine an implicit name to use
return determineImplicitName( catalog, schema, params, serviceRegistry );
return getNamingStrategy( params, serviceRegistry )
.determineSequenceName( catalog, schema, params, serviceRegistry );
}
}
private QualifiedName determineImplicitName(
Identifier catalog,
Identifier schema,
Properties params,
ServiceRegistry serviceRegistry) {
final StrategySelector strategySelector = serviceRegistry.requireService( StrategySelector.class );
final String namingStrategySetting = coalesceSuppliedValues(
() -> {
final String localSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, params );
if ( localSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return localSetting;
},
() -> {
final ConfigurationService configurationService = serviceRegistry.requireService( ConfigurationService.class );
final String globalSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, configurationService.getSettings() );
if ( globalSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return globalSetting;
},
StandardNamingStrategy.class::getName
);
final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy(
ImplicitDatabaseObjectNamingStrategy.class,
namingStrategySetting
);
return namingStrategy.determineSequenceName( catalog, schema, params, serviceRegistry );
}
/**
* Determine the name of the column used to store the generator value in
@ -502,12 +471,9 @@ public class SequenceStyleGenerator
QualifiedName sequenceName,
int initialValue,
int incrementSize) {
if ( isPhysicalSequence( jdbcEnvironment, forceTableUse ) ) {
return buildSequenceStructure( type, params, jdbcEnvironment, sequenceName, initialValue, incrementSize );
}
else {
return buildTableStructure( type, params, jdbcEnvironment, sequenceName, initialValue, incrementSize );
}
return isPhysicalSequence( jdbcEnvironment, forceTableUse )
? buildSequenceStructure( type, params, jdbcEnvironment, sequenceName, initialValue, incrementSize )
: buildTableStructure( type, params, jdbcEnvironment, sequenceName, initialValue, incrementSize );
}
protected boolean isPhysicalSequence(JdbcEnvironment jdbcEnvironment, boolean forceTableUse) {
@ -523,7 +489,6 @@ public class SequenceStyleGenerator
int initialValue,
int incrementSize) {
return new SequenceStructure(
jdbcEnvironment,
determineContributor( params ),
sequenceName,
initialValue,
@ -540,14 +505,11 @@ public class SequenceStyleGenerator
QualifiedName sequenceName,
int initialValue,
int incrementSize) {
final Identifier valueColumnName = determineValueColumnName( params, jdbcEnvironment );
final String contributor = determineContributor( params );
return new TableStructure(
jdbcEnvironment,
contributor,
determineContributor( params ),
sequenceName,
valueColumnName,
determineValueColumnName( params, jdbcEnvironment ),
initialValue,
incrementSize,
params.getProperty( OPTIONS ),
@ -591,21 +553,22 @@ public class SequenceStyleGenerator
* @return sequence increment value
*/
private Number getSequenceIncrementValue(JdbcEnvironment jdbcEnvironment, String sequenceName) {
return jdbcEnvironment.getExtractedDatabaseMetaData().getSequenceInformationList()
.stream()
.filter(
sequenceInformation -> {
QualifiedSequenceName name = sequenceInformation.getSequenceName();
Identifier catalog = name.getCatalogName();
Identifier schema = name.getSchemaName();
return sequenceName.equalsIgnoreCase( name.getSequenceName().getText() )
&& ( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) )
for ( SequenceInformation information :
jdbcEnvironment.getExtractedDatabaseMetaData().getSequenceInformationList() ) {
final QualifiedSequenceName name = information.getSequenceName();
if ( sequenceName.equalsIgnoreCase( name.getSequenceName().getText() )
&& isDefaultSchema( jdbcEnvironment, name.getCatalogName(), name.getSchemaName() ) ) {
final Number incrementValue = information.getIncrementValue();
if ( incrementValue != null ) {
return incrementValue;
}
}
}
return null;
}
private static boolean isDefaultSchema(JdbcEnvironment jdbcEnvironment, Identifier catalog, Identifier schema) {
return ( catalog == null || catalog.equals( jdbcEnvironment.getCurrentCatalog() ) )
&& ( schema == null || schema.equals( jdbcEnvironment.getCurrentSchema() ) );
}
)
.map( SequenceInformation::getIncrementValue )
.filter( Objects::nonNull )
.findFirst()
.orElse( null );
}
}

View File

@ -24,7 +24,6 @@ import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedName;
import org.hibernate.boot.model.relational.QualifiedNameParser;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.engine.config.spi.StandardConverters;
@ -42,7 +41,6 @@ import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.id.PersistentIdentifierGenerator;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jdbc.AbstractReturningWork;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PrimaryKey;
@ -55,10 +53,11 @@ 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.IdentifierGeneratorHelper.getNamingStrategy;
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.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.qualify;
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;
@ -382,53 +381,30 @@ public class TableGenerator implements PersistentIdentifierGenerator {
*/
protected QualifiedName determineGeneratorTableName(Properties params, JdbcEnvironment jdbcEnvironment, ServiceRegistry serviceRegistry) {
final IdentifierHelper identifierHelper = jdbcEnvironment.getIdentifierHelper();
final Identifier catalog = identifierHelper.toIdentifier( getString( CATALOG, params ) );
final Identifier schema = identifierHelper.toIdentifier( getString( SCHEMA, params ) );
final String tableName = getString( TABLE_PARAM, params );
return tableName( params, serviceRegistry, tableName, catalog, schema, identifierHelper );
}
final String explicitTableName = getString( TABLE_PARAM, params );
if ( StringHelper.isNotEmpty( explicitTableName ) ) {
if ( explicitTableName.contains( "." ) ) {
return QualifiedNameParser.INSTANCE.parse( explicitTableName );
private static QualifiedName tableName(
Properties params,
ServiceRegistry serviceRegistry,
String explicitTableName,
Identifier catalog, Identifier schema,
IdentifierHelper identifierHelper) {
if ( isNotEmpty( explicitTableName ) ) {
return explicitTableName.contains(".")
? QualifiedNameParser.INSTANCE.parse( explicitTableName )
: new QualifiedNameParser.NameParts( catalog, schema,
identifierHelper.toIdentifier( explicitTableName ) );
}
else {
return new QualifiedNameParser.NameParts(
catalog,
schema,
identifierHelper.toIdentifier( explicitTableName )
);
return getNamingStrategy( params, serviceRegistry )
.determineTableName( catalog, schema, params, serviceRegistry );
}
}
final StrategySelector strategySelector = serviceRegistry.requireService( StrategySelector.class );
final String namingStrategySetting = coalesceSuppliedValues(
() -> {
final String localSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, params );
if ( localSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return localSetting;
},
() -> {
final ConfigurationService configurationService = serviceRegistry.requireService( ConfigurationService.class );
final String globalSetting = getString( ID_DB_STRUCTURE_NAMING_STRATEGY, configurationService.getSettings() );
if ( globalSetting != null ) {
INCUBATION_LOGGER.incubatingSetting( ID_DB_STRUCTURE_NAMING_STRATEGY );
}
return globalSetting;
},
StandardNamingStrategy.class::getName
);
final ImplicitDatabaseObjectNamingStrategy namingStrategy = strategySelector.resolveStrategy(
ImplicitDatabaseObjectNamingStrategy.class,
namingStrategySetting
);
return namingStrategy.determineTableName( catalog, schema, params, serviceRegistry );
}
/**
* Determine the name of the column used to indicate the segment for each
* row. This column acts as the primary key.
@ -470,11 +446,8 @@ public class TableGenerator implements PersistentIdentifierGenerator {
* @return The name of the value column
*/
protected String determineSegmentValue(Properties params) {
String segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
if ( StringHelper.isEmpty( segmentValue ) ) {
segmentValue = determineDefaultSegmentValue( params );
}
return segmentValue;
final String segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
return isEmpty( segmentValue ) ? determineDefaultSegmentValue( params ) : segmentValue;
}
/**
@ -514,9 +487,9 @@ public class TableGenerator implements PersistentIdentifierGenerator {
protected String buildSelectQuery(String formattedPhysicalTableName, SqlStringGenerationContext context) {
final String alias = "tbl";
final String query = "select " + StringHelper.qualify( alias, valueColumnName )
final String query = "select " + qualify( alias, valueColumnName )
+ " from " + formattedPhysicalTableName + ' ' + alias
+ " where " + StringHelper.qualify( alias, segmentColumnName ) + "=?";
+ " where " + qualify( alias, segmentColumnName ) + "=?";
final LockOptions lockOptions = new LockOptions( LockMode.PESSIMISTIC_WRITE );
lockOptions.setAliasSpecificLockMode( alias, LockMode.PESSIMISTIC_WRITE );
final Map<String,String[]> updateTargetColumnsMap = singletonMap( alias, new String[] { valueColumnName } );
@ -551,8 +524,8 @@ public class TableGenerator implements PersistentIdentifierGenerator {
@Override
public Object generate(final SharedSessionContractImplementor session, final Object obj) {
final SqlStatementLogger statementLogger = session.
getFactory().getJdbcServices()
final SqlStatementLogger statementLogger =
session.getFactory().getJdbcServices()
.getSqlStatementLogger();
final SessionEventListenerManager statsCollector = session.getEventListenerManager();
return optimizer.generate(
@ -591,13 +564,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
selectPS.setString( 1, segmentValue );
final ResultSet selectRS = executeQuery( selectPS, listener, selectQuery, session );
if ( !selectRS.next() ) {
long initializationValue;
if ( storeLastUsedValue ) {
initializationValue = initialValue - 1;
}
else {
initializationValue = initialValue;
}
final long initializationValue = storeLastUsedValue ? initialValue - 1 : initialValue;
value.initialize( initializationValue );
try ( PreparedStatement statement = prepareStatement( connection, insertQuery, logger, listener, session ) ) {
@ -608,13 +575,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
}
}
else {
int defaultValue;
if ( storeLastUsedValue ) {
defaultValue = 0;
}
else {
defaultValue = 1;
}
final int defaultValue = storeLastUsedValue ? 0 : 1;
value.initialize( selectRS, defaultValue );
}
selectRS.close();
@ -646,12 +607,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
while ( rows == 0 );
accessCount++;
if ( storeLastUsedValue ) {
return value.increment();
}
else {
return value;
}
return storeLastUsedValue ? value.increment() : value;
}
private PreparedStatement prepareStatement(
@ -662,13 +618,13 @@ public class TableGenerator implements PersistentIdentifierGenerator {
SharedSessionContractImplementor session) throws SQLException {
logger.logStatement( sql, FormatStyle.BASIC.getFormatter() );
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementCreation = eventManager.beginJdbcPreparedStatementCreationEvent();
final HibernateMonitoringEvent creationEvent = eventManager.beginJdbcPreparedStatementCreationEvent();
try {
listener.jdbcPrepareStatementStart();
return connection.prepareStatement( sql );
}
finally {
eventManager.completeJdbcPreparedStatementCreationEvent( jdbcPreparedStatementCreation, sql );
eventManager.completeJdbcPreparedStatementCreationEvent( creationEvent, sql );
listener.jdbcPrepareStatementEnd();
}
}
@ -679,13 +635,13 @@ public class TableGenerator implements PersistentIdentifierGenerator {
String sql,
SharedSessionContractImplementor session) throws SQLException {
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementExecutionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
final HibernateMonitoringEvent executionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
try {
listener.jdbcExecuteStatementStart();
return ps.executeUpdate();
}
finally {
eventManager.completeJdbcPreparedStatementExecutionEvent( jdbcPreparedStatementExecutionEvent, sql );
eventManager.completeJdbcPreparedStatementExecutionEvent( executionEvent, sql );
listener.jdbcExecuteStatementEnd();
}
}
@ -696,13 +652,13 @@ public class TableGenerator implements PersistentIdentifierGenerator {
String sql,
SharedSessionContractImplementor session) throws SQLException {
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementExecutionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
final HibernateMonitoringEvent executionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
try {
listener.jdbcExecuteStatementStart();
return ps.executeQuery();
}
finally {
eventManager.completeJdbcPreparedStatementExecutionEvent( jdbcPreparedStatementExecutionEvent, sql );
eventManager.completeJdbcPreparedStatementExecutionEvent( executionEvent, sql );
listener.jdbcExecuteStatementEnd();
}
}
@ -720,7 +676,7 @@ public class TableGenerator implements PersistentIdentifierGenerator {
qualifiedTableName.getObjectName(),
(identifier) -> new Table( contributor, namespace, identifier, false )
);
if ( StringHelper.isNotEmpty( options ) ) {
if ( isNotEmpty( options ) ) {
table.setOptions( options );
}
@ -752,15 +708,15 @@ public class TableGenerator implements PersistentIdentifierGenerator {
}
// allow physical naming strategies a chance to kick in
this.physicalTableName = table.getQualifiedTableName();
physicalTableName = table.getQualifiedTableName();
table.addInitCommand( this::generateInsertInitCommand );
}
@Override
public void initialize(SqlStringGenerationContext context) {
String formattedPhysicalTableName = context.format( physicalTableName );
this.selectQuery = buildSelectQuery( formattedPhysicalTableName, context );
this.updateQuery = buildUpdateQuery( formattedPhysicalTableName, context );
this.insertQuery = buildInsertQuery( formattedPhysicalTableName, context );
final String formattedPhysicalTableName = context.format( physicalTableName );
selectQuery = buildSelectQuery( formattedPhysicalTableName, context );
updateQuery = buildUpdateQuery( formattedPhysicalTableName, context );
insertQuery = buildInsertQuery( formattedPhysicalTableName, context );
}
}

View File

@ -12,7 +12,6 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import org.hibernate.AssertionFailure;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.relational.Database;
@ -21,7 +20,6 @@ import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedName;
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.internal.FormatStyle;
import org.hibernate.engine.jdbc.spi.SqlStatementLogger;
import org.hibernate.engine.spi.SessionEventListenerManager;
@ -30,7 +28,6 @@ import org.hibernate.event.spi.EventManager;
import org.hibernate.event.spi.HibernateMonitoringEvent;
import org.hibernate.id.ExportableColumn;
import org.hibernate.id.IdentifierGenerationException;
import org.hibernate.id.IdentifierGeneratorHelper;
import org.hibernate.id.IntegralDataTypeHolder;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jdbc.AbstractReturningWork;
@ -39,6 +36,9 @@ import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;
import static org.hibernate.LockMode.PESSIMISTIC_WRITE;
import static org.hibernate.id.IdentifierGeneratorHelper.getIntegralDataTypeHolder;
/**
* Describes a table used to mimic sequence behavior
*
@ -54,10 +54,10 @@ public class TableStructure implements DatabaseStructure {
private final Identifier logicalValueColumnNameIdentifier;
private final int initialValue;
private final int incrementSize;
private final Class numberType;
private final Class<?> numberType;
private final String options;
private String contributor;
private final String contributor;
private QualifiedName physicalTableName;
private String valueColumnNameText;
@ -70,15 +70,13 @@ public class TableStructure implements DatabaseStructure {
public TableStructure(
JdbcEnvironment jdbcEnvironment,
String contributor,
QualifiedName qualifiedTableName,
Identifier valueColumnNameIdentifier,
int initialValue,
int incrementSize,
Class numberType) {
Class<?> numberType) {
this(
jdbcEnvironment,
contributor,
qualifiedTableName,
valueColumnNameIdentifier,
@ -90,14 +88,13 @@ public class TableStructure implements DatabaseStructure {
}
public TableStructure(
JdbcEnvironment jdbcEnvironment,
String contributor,
QualifiedName qualifiedTableName,
Identifier valueColumnNameIdentifier,
int initialValue,
int incrementSize,
String options,
Class numberType) {
Class<?> numberType) {
this.contributor = contributor;
this.logicalQualifiedTableName = qualifiedTableName;
this.logicalValueColumnNameIdentifier = valueColumnNameIdentifier;
@ -128,47 +125,48 @@ public class TableStructure implements DatabaseStructure {
return accessCounter;
}
@Override
@Override @Deprecated
public String[] getAllSqlForTests() {
return new String[] { selectQuery, updateQuery };
}
@Override
@Override @Deprecated
public void prepare(Optimizer optimizer) {
applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
}
private IntegralDataTypeHolder makeValue() {
return IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType );
return getIntegralDataTypeHolder( numberType );
}
@Override
public AccessCallback buildCallback(final SharedSessionContractImplementor session) {
final SqlStatementLogger statementLogger = session.getFactory().getJdbcServices()
.getSqlStatementLogger();
if ( selectQuery == null || updateQuery == null ) {
throw new AssertionFailure( "SequenceStyleGenerator's TableStructure was not properly initialized" );
}
final SessionEventListenerManager statsCollector = session.getEventListenerManager();
final SqlStatementLogger statementLogger =
session.getFactory().getJdbcServices()
.getSqlStatementLogger();
return new AccessCallback() {
@Override
public IntegralDataTypeHolder getNextValue() {
return session.getTransactionCoordinator().createIsolationDelegate().delegateWork(
new AbstractReturningWork<IntegralDataTypeHolder>() {
new AbstractReturningWork<>() {
@Override
public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
final IntegralDataTypeHolder value = makeValue();
int rows;
do {
try (PreparedStatement selectStatement = prepareStatement(
try ( PreparedStatement selectStatement = prepareStatement(
connection,
selectQuery,
statementLogger,
statsCollector,
session
)) {
) ) {
final ResultSet selectRS = executeQuery(
selectStatement,
statsCollector,
@ -189,13 +187,13 @@ public class TableStructure implements DatabaseStructure {
}
try (PreparedStatement updatePS = prepareStatement(
try ( PreparedStatement updatePS = prepareStatement(
connection,
updateQuery,
statementLogger,
statsCollector,
session
)) {
) ) {
final int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
final IntegralDataTypeHolder updateValue = value.copy().add( increment );
updateValue.bind( updatePS, 1 );
@ -227,18 +225,18 @@ public class TableStructure implements DatabaseStructure {
private PreparedStatement prepareStatement(
Connection connection,
String sql,
SqlStatementLogger statementLogger,
SqlStatementLogger logger,
SessionEventListenerManager statsCollector,
SharedSessionContractImplementor session) throws SQLException {
statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() );
logger.logStatement( sql, FormatStyle.BASIC.getFormatter() );
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementCreation = eventManager.beginJdbcPreparedStatementCreationEvent();
final HibernateMonitoringEvent creationEvent = eventManager.beginJdbcPreparedStatementCreationEvent();
try {
statsCollector.jdbcPrepareStatementStart();
return connection.prepareStatement( sql );
}
finally {
eventManager.completeJdbcPreparedStatementCreationEvent( jdbcPreparedStatementCreation, sql );
eventManager.completeJdbcPreparedStatementCreationEvent( creationEvent, sql );
statsCollector.jdbcPrepareStatementEnd();
}
}
@ -249,13 +247,13 @@ public class TableStructure implements DatabaseStructure {
String sql,
SharedSessionContractImplementor session) throws SQLException {
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementExecutionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
final HibernateMonitoringEvent executionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
try {
statsCollector.jdbcExecuteStatementStart();
return ps.executeUpdate();
}
finally {
eventManager.completeJdbcPreparedStatementExecutionEvent( jdbcPreparedStatementExecutionEvent, sql );
eventManager.completeJdbcPreparedStatementExecutionEvent( executionEvent, sql );
statsCollector.jdbcExecuteStatementEnd();
}
@ -267,13 +265,13 @@ public class TableStructure implements DatabaseStructure {
String sql,
SharedSessionContractImplementor session) throws SQLException {
final EventManager eventManager = session.getEventManager();
final HibernateMonitoringEvent jdbcPreparedStatementExecutionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
final HibernateMonitoringEvent executionEvent = eventManager.beginJdbcPreparedStatementExecutionEvent();
try {
statsCollector.jdbcExecuteStatementStart();
return ps.executeQuery();
}
finally {
eventManager.completeJdbcPreparedStatementExecutionEvent( jdbcPreparedStatementExecutionEvent, sql );
eventManager.completeJdbcPreparedStatementExecutionEvent( executionEvent, sql );
statsCollector.jdbcExecuteStatementEnd();
}
}
@ -285,8 +283,6 @@ public class TableStructure implements DatabaseStructure {
@Override
public void registerExportables(Database database) {
final JdbcEnvironment jdbcEnvironment = database.getJdbcEnvironment();
final Dialect dialect = jdbcEnvironment.getDialect();
final Namespace namespace = database.locateNamespace(
logicalQualifiedTableName.getCatalogName(),
@ -294,7 +290,7 @@ public class TableStructure implements DatabaseStructure {
);
Table table = namespace.locateTable( logicalQualifiedTableName.getObjectName() );
boolean tableCreated = false;
final boolean tableCreated;
if ( table == null ) {
table = namespace.createTable(
logicalQualifiedTableName.getObjectName(),
@ -302,11 +298,14 @@ public class TableStructure implements DatabaseStructure {
);
tableCreated = true;
}
this.physicalTableName = table.getQualifiedTableName();
else {
tableCreated = false;
}
physicalTableName = table.getQualifiedTableName();
valueColumnNameText = logicalValueColumnNameIdentifier.render( dialect );
valueColumnNameText = logicalValueColumnNameIdentifier.render( database.getJdbcEnvironment().getDialect() );
if ( tableCreated ) {
ExportableColumn valueColumn = new ExportableColumn(
final ExportableColumn valueColumn = new ExportableColumn(
database,
table,
valueColumnNameText,
@ -324,15 +323,15 @@ public class TableStructure implements DatabaseStructure {
@Override
public void initialize(SqlStringGenerationContext context) {
Dialect dialect = context.getDialect();
final Dialect dialect = context.getDialect();
final String formattedPhysicalTableName = context.format( physicalTableName );
final String lockedTable =
dialect.appendLockHint( new LockOptions( PESSIMISTIC_WRITE ), formattedPhysicalTableName )
+ dialect.getForUpdateString();
selectQuery = "select " + valueColumnNameText + " as id_val" +
" from " + lockedTable ;
String formattedPhysicalTableName = context.format( physicalTableName );
this.selectQuery = "select " + valueColumnNameText + " as id_val" +
" from " + dialect.appendLockHint( new LockOptions( LockMode.PESSIMISTIC_WRITE ), formattedPhysicalTableName ) +
dialect.getForUpdateString();
this.updateQuery = "update " + formattedPhysicalTableName +
updateQuery = "update " + formattedPhysicalTableName +
" set " + valueColumnNameText + "= ?" +
" where " + valueColumnNameText + "=?";
}

View File

@ -50,6 +50,7 @@ import org.hibernate.query.sqm.tree.domain.SqmPath;
import org.hibernate.query.sqm.tree.expression.SqmExpression;
import org.hibernate.query.sqm.tree.expression.SqmParameter;
import org.hibernate.query.sqm.tree.expression.SqmStar;
import org.hibernate.query.sqm.tree.from.SqmRoot;
import org.hibernate.query.sqm.tree.insert.SqmConflictClause;
import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement;
import org.hibernate.query.sqm.tree.insert.SqmInsertStatement;
@ -107,7 +108,6 @@ import org.hibernate.sql.results.internal.SqlSelectionImpl;
import org.hibernate.sql.results.spi.ListResultsConsumer;
import org.hibernate.generator.Generator;
import org.hibernate.type.BasicType;
import org.hibernate.type.spi.TypeConfiguration;
/**
*
@ -172,18 +172,16 @@ public class CteInsertHandler implements InsertHandler {
final SqmInsertStatement<?> sqmInsertStatement = getSqmStatement();
final SessionFactoryImplementor factory = executionContext.getSession().getFactory();
final EntityPersister entityDescriptor = getEntityDescriptor().getEntityPersister();
final String explicitDmlTargetAlias;
if ( sqmInsertStatement.getTarget().getExplicitAlias() == null ) {
explicitDmlTargetAlias = "dml_target";
}
else {
explicitDmlTargetAlias = sqmInsertStatement.getTarget().getExplicitAlias();
}
final SqmRoot<?> target = sqmInsertStatement.getTarget();
final String explicitDmlTargetAlias =
target.getExplicitAlias() == null
? "dml_target"
: target.getExplicitAlias();
final MultiTableSqmMutationConverter sqmConverter = new MultiTableSqmMutationConverter(
entityDescriptor,
sqmInsertStatement,
sqmInsertStatement.getTarget(),
target,
explicitDmlTargetAlias,
domainParameterXref,
executionContext.getQueryOptions(),
@ -383,8 +381,10 @@ public class CteInsertHandler implements InsertHandler {
rowNumberColumnReference
)
);
final String fragment = ( (BulkInsertionCapableIdentifierGenerator) entityDescriptor.getGenerator() )
.determineBulkInsertionIdentifierGenerationSelectFragment(
final BulkInsertionCapableIdentifierGenerator generator =
(BulkInsertionCapableIdentifierGenerator) entityDescriptor.getGenerator();
final String fragment =
generator.determineBulkInsertionIdentifierGenerationSelectFragment(
sessionFactory.getSqlStringGenerationContext()
);
rowsWithSequenceQuery.getSelectClause().addSqlSelection(

View File

@ -6,7 +6,6 @@
*/
package org.hibernate.orm.test.schemaupdate;
import java.sql.SQLException;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
@ -63,13 +62,12 @@ public class SchemaUpdateTableBackedSequenceTest extends BaseUnitTestCase {
}
@Test
public void testCreateTableOnUpdate() throws SQLException {
public void testCreateTableOnUpdate() {
Metadata metadata = new MetadataSources( ssr ).buildMetadata();
Database database = metadata.getDatabase();
TableStructure tableStructure = new TableStructure(
database.getJdbcEnvironment(),
"orm",
new QualifiedTableName( null, null, Identifier.toIdentifier( "test_seq" ) ),
Identifier.toIdentifier( "nextval" ),
@ -79,7 +77,7 @@ public class SchemaUpdateTableBackedSequenceTest extends BaseUnitTestCase {
);
tableStructure.registerExportables( database );
// lets make sure the InitCommand is there
// let's make sure the InitCommand is there
assertEquals( 1, database.getDefaultNamespace().getTables().size() );
Table table = database.getDefaultNamespace().getTables().iterator().next();
SqlStringGenerationContext context = SqlStringGenerationContextImpl.forTests( database.getJdbcEnvironment(), null, null );

View File

@ -42,7 +42,7 @@ public class OrderedSequenceStructure extends SequenceStructure {
int incrementSize,
boolean noCache,
Class<?> numberType) {
super( jdbcEnvironment, "envers", qualifiedSequenceName, initialValue, incrementSize, numberType );
super( "envers", qualifiedSequenceName, initialValue, incrementSize, numberType );
this.sequenceObject = new OrderedSequence();
final Dialect dialect = DialectDelegateWrapper.extractRealDialect( jdbcEnvironment.getDialect() );
if ( dialect instanceof OracleDialect ) {

View File

@ -17,7 +17,6 @@ import org.hibernate.boot.model.relational.Namespace;
import org.hibernate.boot.model.relational.QualifiedNameImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.id.enhanced.SequenceStructure;
import org.hibernate.testing.DialectChecks;
import org.hibernate.testing.RequiresDialectFeature;
@ -52,7 +51,6 @@ public class ExportIdentifierTest extends BaseUnitTestCase {
int namespaceSize = 0;
for ( Namespace namespace : database.getNamespaces() ) {
final SequenceStructure sequenceStructure = new SequenceStructure(
ssr.getService( JdbcEnvironment.class ),
"envers",
new QualifiedNameImpl(
namespace.getName(),