From 6a630e3515fa7343524899bf8fb1fa70110ce4cd Mon Sep 17 00:00:00 2001 From: Gavin Date: Thu, 1 Dec 2022 20:30:50 +0100 Subject: [PATCH] make PostInsertIdentifierGenerator extend InDatabaseGenerator --- .../InFlightMetadataCollectorImpl.java | 4 +- .../identity/IdentityColumnSupport.java | 9 + .../dialect/temptable/TemporaryTable.java | 5 +- .../spi/SessionFactoryDelegatingImpl.java | 4 +- .../engine/spi/SessionFactoryImplementor.java | 4 +- .../internal/AbstractSaveEventListener.java | 43 ++-- .../id/AbstractPostInsertGenerator.java | 28 +- ...lkInsertionCapableIdentifierGenerator.java | 8 +- .../java/org/hibernate/id/Configurable.java | 5 - .../org/hibernate/id/IdentityGenerator.java | 1 - .../org/hibernate/id/IncrementGenerator.java | 14 +- .../id/PostInsertIdentifierGenerator.java | 14 +- .../id/PostInsertIdentityPersister.java | 1 + .../org/hibernate/id/SelectGenerator.java | 44 ++-- .../hibernate/id/enhanced/TableGenerator.java | 241 +++++++++--------- .../factory/IdentifierGeneratorFactory.java | 8 +- .../internal/IdentifierGeneratorUtil.java | 4 +- .../StandardIdentifierGeneratorFactory.java | 27 +- .../id/insert/AbstractReturningDelegate.java | 5 +- .../id/insert/AbstractSelectingDelegate.java | 36 +-- .../id/insert/BasicSelectingDelegate.java | 6 +- .../id/insert/InsertReturningDelegate.java | 9 +- .../id/insert/InsertSelectIdentityInsert.java | 3 +- .../internal/SessionFactoryImpl.java | 8 +- .../internal/StatelessSessionImpl.java | 37 +-- .../java/org/hibernate/mapping/Component.java | 29 ++- .../java/org/hibernate/mapping/KeyValue.java | 3 +- .../org/hibernate/mapping/SimpleValue.java | 30 +-- .../AbstractCollectionPersister.java | 25 +- .../entity/AbstractEntityPersister.java | 10 +- .../persister/entity/EntityPersister.java | 4 +- .../mutation/AbstractMutationCoordinator.java | 5 + .../entity/mutation/InsertCoordinator.java | 9 +- .../mutation/UpdateCoordinatorStandard.java | 19 +- .../query/sqm/internal/QuerySqmImpl.java | 3 +- .../internal/cte/CteInsertHandler.java | 17 +- .../temptable/InsertExecutionDelegate.java | 32 +-- .../temptable/TableBasedInsertHandler.java | 3 +- .../sqm/sql/BaseSqmToSqlAstConverter.java | 15 +- .../tuple/GeneratedAlwaysValueGeneration.java | 2 +- .../tuple/GeneratedValueGeneration.java | 2 +- .../hibernate/tuple/IdentifierAttribute.java | 2 +- .../hibernate/tuple/IdentifierProperty.java | 12 +- .../hibernate/tuple/InDatabaseGenerator.java | 8 +- .../org/hibernate/tuple/PropertyFactory.java | 2 +- .../org/hibernate/tuple/ValueGeneration.java | 4 +- .../tuple/entity/EntityMetamodel.java | 4 +- .../orm/test/hql/BulkManipulationTest.java | 9 +- 48 files changed, 413 insertions(+), 404 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index e0c6f380f9..9c5b8fc067 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -102,7 +102,7 @@ import org.hibernate.metamodel.CollectionClassification; import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.query.named.NamedObjectRepository; import org.hibernate.query.sqm.function.SqmFunctionDescriptor; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.spi.TypeConfiguration; @@ -2315,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.createGenerator( + final Generator generator = identifierValueBinding.createGenerator( bootstrapContext.getIdentifierGeneratorFactory(), dialect, entityBinding diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupport.java b/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupport.java index d5ec3034e1..3675e3da2f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupport.java @@ -111,6 +111,15 @@ public interface IdentityColumnSupport { */ String getIdentityInsertString(); + /** + * Is there a keyword used to insert a generated value into an identity column. + * + * @return {@code true} if the dialect does not support inserts that specify no column values. + */ + default boolean hasIdentityInsertKeyword() { + return getIdentityInsertString() != null; + } + /** * The Delegate for dealing with IDENTITY columns using JDBC3 getGeneratedKeys * diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java index 54cd32c937..a912773933 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/temptable/TemporaryTable.java @@ -41,6 +41,7 @@ import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.SingleTableEntityPersister; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.BasicType; import org.hibernate.type.StandardBasicTypes; @@ -253,8 +254,8 @@ public class TemporaryTable implements Exportable, Contributable { final PersistentClass entityBinding = runtimeModelCreationContext.getBootModel() .getEntityBinding( entityDescriptor.getEntityName() ); - final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator(); - final boolean identityColumn = identifierGenerator instanceof PostInsertIdentifierGenerator; + final Generator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator(); + final boolean identityColumn = identifierGenerator.generatedByDatabase(); final boolean hasOptimizer; if ( identityColumn ) { hasOptimizer = false; diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java index a32612e112..fb6a47fbcb 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java @@ -46,7 +46,7 @@ import org.hibernate.query.spi.QueryEngine; import org.hibernate.relational.SchemaManager; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.stat.spi.StatisticsImplementor; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.Type; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.spi.TypeConfiguration; @@ -185,7 +185,7 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor, } @Override - public InMemoryGenerator getGenerator(String rootEntityName) { + public Generator getGenerator(String rootEntityName) { return delegate.getGenerator( rootEntityName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java index 2b3276380d..759d7e08e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryImplementor.java @@ -33,7 +33,7 @@ import org.hibernate.query.sqm.spi.SqmCreationContext; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.sql.ast.spi.SqlAstCreationContext; import org.hibernate.stat.spi.StatisticsImplementor; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.spi.TypeConfiguration; @@ -130,7 +130,7 @@ public interface SessionFactoryImplementor /** * Get the identifier generator for the hierarchy */ - InMemoryGenerator getGenerator(String rootEntityName); + Generator getGenerator(String rootEntityName); EntityNotFoundDelegate getEntityNotFoundDelegate(); diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java index f7d44efe46..f3b11ac094 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/AbstractSaveEventListener.java @@ -34,6 +34,8 @@ import org.hibernate.jpa.event.spi.CallbackRegistry; import org.hibernate.jpa.event.spi.CallbackRegistryConsumer; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; +import org.hibernate.tuple.Generator; +import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.Type; import org.hibernate.type.TypeHelper; @@ -110,27 +112,30 @@ public abstract class AbstractSaveEventListener processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes ); - EntityPersister persister = source.getEntityPersister( entityName, entity ); - Object generatedId = persister.getGenerator().generate( source, entity, null ); - if ( generatedId == null ) { - throw new IdentifierGenerationException( "null id generated for: " + entity.getClass() ); - } - else if ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) { - return source.getIdentifier( entity ); - } - else if ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) { - return performSave( entity, null, persister, true, context, source, requiresImmediateIdAccess ); + final EntityPersister persister = source.getEntityPersister( entityName, entity ); + Generator generator = persister.getGenerator(); + if ( !generator.generatedByDatabase() ) { + Object generatedId = ( (InMemoryGenerator) generator ).generate( source, entity, null ); + if ( generatedId == null ) { + throw new IdentifierGenerationException( "null id generated for: " + entity.getClass() ); + } + else if ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) { + return source.getIdentifier( entity ); + } + else { + // TODO: define toString()s for generators + if ( LOG.isDebugEnabled() ) { + LOG.debugf( + "Generated identifier: %s, using strategy: %s", + persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ), + generator.getClass().getName() + ); + } + return performSave( entity, generatedId, persister, false, context, source, true ); + } } else { - // TODO: define toString()s for generators - if ( LOG.isDebugEnabled() ) { - LOG.debugf( - "Generated identifier: %s, using strategy: %s", - persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ), - persister.getGenerator().getClass().getName() - ); - } - return performSave( entity, generatedId, persister, false, context, source, true ); + return performSave( entity, null, persister, true, context, source, requiresImmediateIdAccess ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java index a70392ac35..66b2b7f0c7 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java @@ -7,7 +7,11 @@ package org.hibernate.id; import org.hibernate.boot.model.relational.SqlStringGenerationContext; -import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.dialect.Dialect; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.type.Type; + +import java.util.Properties; /** * Basic implementation of the {@link PostInsertIdentifierGenerator} contract. @@ -16,18 +20,22 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; */ public abstract class AbstractPostInsertGenerator implements PostInsertIdentifierGenerator, BulkInsertionCapableIdentifierGenerator { - @Override - public Object generate(SharedSessionContractImplementor s, Object obj) { - return IdentifierGeneratorHelper.POST_INSERT_INDICATOR; - } - - @Override - public boolean supportsBulkInsertionIdentifierGeneration() { - return true; - } @Override public String determineBulkInsertionIdentifierGenerationSelectFragment(SqlStringGenerationContext context) { return null; } + + @Override + public boolean referenceColumnsInSql(Dialect dialect) { + return dialect.getIdentityColumnSupport().hasIdentityInsertKeyword(); + } + + @Override + public String[] getReferencedColumnValues(Dialect dialect) { + return new String[] { dialect.getIdentityColumnSupport().getIdentityInsertString() }; + } + + @Override + public void configure(Type type, Properties params, ServiceRegistry serviceRegistry) {} } diff --git a/hibernate-core/src/main/java/org/hibernate/id/BulkInsertionCapableIdentifierGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/BulkInsertionCapableIdentifierGenerator.java index 7deb2a7ac3..e4332ef9ed 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/BulkInsertionCapableIdentifierGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/BulkInsertionCapableIdentifierGenerator.java @@ -7,7 +7,7 @@ package org.hibernate.id; import org.hibernate.boot.model.relational.SqlStringGenerationContext; -import org.hibernate.id.factory.spi.StandardGenerator; +import org.hibernate.tuple.Generator; /** * Specialized contract for {@link IdentifierGenerator} implementations capable of being used in conjunction @@ -15,7 +15,7 @@ import org.hibernate.id.factory.spi.StandardGenerator; * * @author Steve Ebersole */ -public interface BulkInsertionCapableIdentifierGenerator extends StandardGenerator { +public interface BulkInsertionCapableIdentifierGenerator extends Generator { /** * Given the configuration of this generator, is identifier generation as part of bulk insertion supported? *

@@ -24,7 +24,9 @@ public interface BulkInsertionCapableIdentifierGenerator extends StandardGenerat * * @return {@code true} if bulk insertions are supported; {@code false} otherwise. */ - boolean supportsBulkInsertionIdentifierGeneration(); + default boolean supportsBulkInsertionIdentifierGeneration() { + return true; + } /** * Return the select expression fragment, if any, that generates the identifier values. diff --git a/hibernate-core/src/main/java/org/hibernate/id/Configurable.java b/hibernate-core/src/main/java/org/hibernate/id/Configurable.java index 225d1ea3f1..d927d7ffda 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/Configurable.java +++ b/hibernate-core/src/main/java/org/hibernate/id/Configurable.java @@ -15,14 +15,9 @@ import org.hibernate.type.Type; /** * An {@link IdentifierGenerator} that supports "configuration". * - * @deprecated All methods are already defined in {@link IdentifierGenerator}. - * Just implement {@link IdentifierGenerator}. - * @see IdentifierGenerator - * * @author Gavin King * @author Steve Ebersole */ -@Deprecated public interface Configurable { /** * Configure this instance, given the value of parameters diff --git a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java index 5b648110e2..b7a0d0752f 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/IdentityGenerator.java @@ -42,5 +42,4 @@ public class IdentityGenerator extends AbstractPostInsertGenerator { return new BasicSelectingDelegate( persister, dialect ); } } - } diff --git a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java index 1b66338f28..b4bcd17911 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/IncrementGenerator.java @@ -47,7 +47,7 @@ import org.hibernate.type.Type; public class IncrementGenerator implements StandardGenerator { private static final CoreMessageLogger LOG = CoreLogging.messageLogger( IncrementGenerator.class ); - private Class returnClass; + private Class returnClass; private String column; private List physicalTableNames; private String sql; @@ -106,27 +106,27 @@ public class IncrementGenerator implements StandardGenerator { @Override public void initialize(SqlStringGenerationContext context) { - StringBuilder buf = new StringBuilder(); + StringBuilder union = new StringBuilder(); for ( int i = 0; i < physicalTableNames.size(); i++ ) { final String tableName = context.format( physicalTableNames.get( i ) ); if ( physicalTableNames.size() > 1 ) { - buf.append( "select max(" ).append( column ).append( ") as mx from " ); + union.append( "select max(" ).append( column ).append( ") as mx from " ); } - buf.append( tableName ); + union.append( tableName ); if ( i < physicalTableNames.size() - 1 ) { - buf.append( " union " ); + union.append( " union " ); } } String maxColumn; if ( physicalTableNames.size() > 1 ) { - buf.insert( 0, "( " ).append( " ) ids_" ); + union.insert( 0, "( " ).append( " ) ids_" ); maxColumn = "ids_.mx"; } else { maxColumn = column; } - sql = "select max(" + maxColumn + ") from " + buf.toString(); + sql = "select max(" + maxColumn + ") from " + union; } private void initializePreviousValueHolder(SharedSessionContractImplementor session) { diff --git a/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java index 2d6d4e93b0..ed34fdfb44 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java @@ -8,20 +8,28 @@ package org.hibernate.id; import org.hibernate.HibernateException; import org.hibernate.dialect.Dialect; -import org.hibernate.id.factory.spi.StandardGenerator; import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; +import org.hibernate.tuple.GenerationTiming; +import org.hibernate.tuple.InDatabaseGenerator; + +import static org.hibernate.tuple.GenerationTiming.INSERT; /** * @author Gavin King */ -public interface PostInsertIdentifierGenerator extends StandardGenerator { +public interface PostInsertIdentifierGenerator extends InDatabaseGenerator, Configurable { InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate( PostInsertIdentityPersister persister, Dialect dialect, boolean isGetGeneratedKeysEnabled) throws HibernateException; @Override - default boolean supportsJdbcBatchInserts() { + default GenerationTiming getGenerationTiming() { + return INSERT; + } + + @Override + default boolean writePropertyValue() { return false; } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java b/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java index 0b70bc4bb8..a041465fe6 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java @@ -5,6 +5,7 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.id; + import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.mutation.EntityMutationTarget; diff --git a/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java index 4b8222a9c1..efcb9ebb9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java @@ -91,18 +91,15 @@ public class SelectGenerator extends AbstractPostInsertGenerator { private final String idSelectString; - public SelectGeneratorDelegate( - PostInsertIdentityPersister persister, - Dialect dialect, - String configuredPropertyName) { + public SelectGeneratorDelegate(PostInsertIdentityPersister persister, Dialect dialect, String propertyName) { super( persister ); this.persister = persister; this.dialect = dialect; - this.uniqueKeyPropertyName = determineNameOfPropertyToUse( persister, configuredPropertyName ); + this.uniqueKeyPropertyName = determineNameOfPropertyToUse( persister, propertyName ); - idSelectString = persister.getSelectByUniqueKeyString( uniqueKeyPropertyName ); - uniqueKeyType = persister.getPropertyType( uniqueKeyPropertyName ); + idSelectString = persister.getSelectByUniqueKeyString(this.uniqueKeyPropertyName); + uniqueKeyType = persister.getPropertyType(this.uniqueKeyPropertyName); idType = (BasicType) persister.getIdentifierType(); } @@ -116,37 +113,28 @@ public class SelectGenerator extends AbstractPostInsertGenerator { } @Override - public TableInsertBuilder createTableInsertBuilder(BasicEntityIdentifierMapping identifierMapping, Expectation expectation, SessionFactoryImplementor sessionFactory) { - return new TableInsertBuilderStandard( - persister, - persister.getIdentifierTableMapping(), - sessionFactory - ); + public TableInsertBuilder createTableInsertBuilder( + BasicEntityIdentifierMapping identifierMapping, + Expectation expectation, + SessionFactoryImplementor sessionFactory) { + return new TableInsertBuilderStandard( persister, persister.getIdentifierTableMapping(), sessionFactory ); } - protected void bindParameters( - Object entity, PreparedStatement ps, SharedSessionContractImplementor session) throws SQLException { + protected void bindParameters(Object entity, PreparedStatement ps, SharedSessionContractImplementor session) + throws SQLException { Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName ); uniqueKeyType.nullSafeSet( ps, uniqueKeyValue, 1, session ); } @Override - protected Object extractGeneratedValue( - Object entity, - ResultSet rs, - SharedSessionContractImplementor session) throws SQLException { + protected Object extractGeneratedValue(Object entity, ResultSet rs, SharedSessionContractImplementor session) + throws SQLException { if ( !rs.next() ) { - throw new IdentifierGenerationException( - "the inserted row could not be located by the unique key: " + - uniqueKeyPropertyName - ); + throw new IdentifierGenerationException( "the inserted row could not be located by the unique key: " + + uniqueKeyPropertyName ); } - return idType.getJdbcValueExtractor().extract( - rs, - 1, - session - ); + return idType.getJdbcValueExtractor().extract( rs, 1, session ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java index 076eb360f9..94d9160a28 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java @@ -27,7 +27,6 @@ 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.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.StandardConverters; import org.hibernate.engine.jdbc.Size; @@ -43,7 +42,6 @@ import org.hibernate.id.IntegralDataTypeHolder; import org.hibernate.id.PersistentIdentifierGenerator; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; -import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.mapping.Column; import org.hibernate.mapping.PrimaryKey; @@ -58,6 +56,9 @@ import org.jboss.logging.Logger; import static org.hibernate.cfg.AvailableSettings.ID_DB_STRUCTURE_NAMING_STRATEGY; 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; /** * An enhanced version of table-based id generation. @@ -343,12 +344,12 @@ public class TableGenerator implements PersistentIdentifierGenerator { initialValue = determineInitialValue(parameters); incrementSize = determineIncrementSize(parameters); - final String optimizationStrategy = ConfigurationHelper.getString( + final String optimizationStrategy = getString( OPT_PARAM, parameters, OptimizerFactory.determineImplicitOptimizerName( incrementSize, parameters) ); - int optimizerInitialValue = ConfigurationHelper.getInt( INITIAL_PARAM, parameters, -1 ); + int optimizerInitialValue = getInt( INITIAL_PARAM, parameters, -1 ); optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), @@ -373,17 +374,17 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The table name to use. */ protected QualifiedName determineGeneratorTableName(Properties params, JdbcEnvironment jdbcEnvironment, ServiceRegistry serviceRegistry) { - final String explicitTableName = ConfigurationHelper.getString( TABLE_PARAM, params ); + final String explicitTableName = getString( TABLE_PARAM, params ); if ( StringHelper.isNotEmpty( explicitTableName ) ) { if ( explicitTableName.contains( "." ) ) { return QualifiedNameParser.INSTANCE.parse( explicitTableName ); } else { final Identifier catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier( - ConfigurationHelper.getString( CATALOG, params ) + getString( CATALOG, params ) ); final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( - ConfigurationHelper.getString( SCHEMA, params ) + getString( SCHEMA, params ) ); return new QualifiedNameParser.NameParts( catalog, @@ -397,7 +398,7 @@ public class TableGenerator implements PersistentIdentifierGenerator { 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 ); } @@ -405,7 +406,7 @@ public class TableGenerator implements PersistentIdentifierGenerator { }, () -> { 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 ); } @@ -420,10 +421,10 @@ public class TableGenerator implements PersistentIdentifierGenerator { ); final Identifier catalog = jdbcEnvironment.getIdentifierHelper().toIdentifier( - ConfigurationHelper.getString( CATALOG, params ) + getString( CATALOG, params ) ); final Identifier schema = jdbcEnvironment.getIdentifierHelper().toIdentifier( - ConfigurationHelper.getString( SCHEMA, params ) + getString( SCHEMA, params ) ); return namingStrategy.determineTableName( catalog, schema, params, serviceRegistry ); @@ -441,7 +442,7 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The name of the segment column */ protected String determineSegmentColumnName(Properties params, JdbcEnvironment jdbcEnvironment) { - final String name = ConfigurationHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN ); + final String name = getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN ); return jdbcEnvironment.getIdentifierHelper().toIdentifier( name ).render( jdbcEnvironment.getDialect() ); } @@ -456,7 +457,7 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The name of the value column */ protected String 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 ).render( jdbcEnvironment.getDialect() ); } @@ -485,7 +486,7 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The default segment value to use. */ protected String determineDefaultSegmentValue(Properties params) { - final boolean preferSegmentPerEntity = ConfigurationHelper.getBoolean( CONFIG_PREFER_SEGMENT_PER_ENTITY, params, false ); + final boolean preferSegmentPerEntity = getBoolean( CONFIG_PREFER_SEGMENT_PER_ENTITY, params, false ); final String defaultToUse = preferSegmentPerEntity ? params.getProperty( TABLE ) : DEF_SEGMENT_VALUE; LOG.usingDefaultIdGeneratorSegmentValue( qualifiedTableName.render(), segmentColumnName, defaultToUse ); return defaultToUse; @@ -501,23 +502,23 @@ public class TableGenerator implements PersistentIdentifierGenerator { * @return The size of the segment column */ protected int determineSegmentColumnSize(Properties params) { - return ConfigurationHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH ); + return getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH ); } protected int determineInitialValue(Properties params) { - return ConfigurationHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); + return getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE ); } protected int determineIncrementSize(Properties params) { - return ConfigurationHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE ); + 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 ) + - " from " + formattedPhysicalTableName + ' ' + alias + - " where " + StringHelper.qualify( alias, segmentColumnName ) + "=?"; + final String query = "select " + StringHelper.qualify( alias, valueColumnName ) + + " from " + formattedPhysicalTableName + ' ' + alias + + " 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 } ); @@ -525,13 +526,14 @@ public class TableGenerator implements PersistentIdentifierGenerator { } protected String buildUpdateQuery(String formattedPhysicalTableName, SqlStringGenerationContext context) { - return "update " + formattedPhysicalTableName + - " set " + valueColumnName + "=? " + - " where " + valueColumnName + "=? and " + segmentColumnName + "=?"; + return "update " + formattedPhysicalTableName + + " set " + valueColumnName + "=? " + + " where " + valueColumnName + "=? and " + segmentColumnName + "=?"; } protected String buildInsertQuery(String formattedPhysicalTableName, SqlStringGenerationContext context) { - return "insert into " + formattedPhysicalTableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)"; + return "insert into " + formattedPhysicalTableName + + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)"; } protected InitCommand generateInsertInitCommand(SqlStringGenerationContext context) { @@ -540,7 +542,9 @@ public class TableGenerator implements PersistentIdentifierGenerator { if ( storeLastUsedValue ) { value = initialValue - 1; } - return new InitCommand( "insert into " + renderedTableName + "(" + segmentColumnName + ", " + valueColumnName + ")" + " values ('" + segmentValue + "'," + ( value ) + ")" ); + return new InitCommand( "insert into " + renderedTableName + + "(" + segmentColumnName + ", " + valueColumnName + ")" + + " values ('" + segmentValue + "'," + ( value ) + ")" ); } private IntegralDataTypeHolder makeValue() { @@ -559,93 +563,10 @@ public class TableGenerator implements PersistentIdentifierGenerator { @Override public IntegralDataTypeHolder getNextValue() { return session.getTransactionCoordinator().createIsolationDelegate().delegateWork( - new AbstractReturningWork() { + new AbstractReturningWork<>() { @Override public IntegralDataTypeHolder execute(Connection connection) throws SQLException { - final IntegralDataTypeHolder value = makeValue(); - int rows; - do { - - try (PreparedStatement selectPS = prepareStatement( - connection, - selectQuery, - statementLogger, - statsCollector - )) { - selectPS.setString( 1, segmentValue ); - final ResultSet selectRS = executeQuery( selectPS, statsCollector ); - if ( !selectRS.next() ) { - long initializationValue; - if ( storeLastUsedValue ) { - initializationValue = initialValue - 1; - } - else { - initializationValue = initialValue; - } - value.initialize( initializationValue ); - - try (PreparedStatement insertPS = prepareStatement( - connection, - insertQuery, - statementLogger, - statsCollector - )) { - LOG.tracef( "binding parameter [%s] - [%s]", 1, segmentValue ); - insertPS.setString( 1, segmentValue ); - value.bind( insertPS, 2 ); - executeUpdate( insertPS, statsCollector ); - } - } - else { - int defaultValue; - if ( storeLastUsedValue ) { - defaultValue = 0; - } - else { - defaultValue = 1; - } - value.initialize( selectRS, defaultValue ); - } - selectRS.close(); - } - catch (SQLException e) { - LOG.unableToReadOrInitHiValue( e ); - throw e; - } - - - try (PreparedStatement updatePS = prepareStatement( - connection, - updateQuery, - statementLogger, - statsCollector - )) { - final IntegralDataTypeHolder updateValue = value.copy(); - if ( optimizer.applyIncrementSizeToSourceValues() ) { - updateValue.add( incrementSize ); - } - else { - updateValue.increment(); - } - updateValue.bind( updatePS, 1 ); - value.bind( updatePS, 2 ); - updatePS.setString( 3, segmentValue ); - rows = executeUpdate( updatePS, statsCollector ); - } - catch (SQLException e) { - LOG.unableToUpdateQueryHiValue( physicalTableName.render(), e ); - throw e; - } - } - while ( rows == 0 ); - - accessCount++; - if ( storeLastUsedValue ) { - return value.increment(); - } - else { - return value; - } + return nextValue( connection, statementLogger, statsCollector ); } }, true @@ -660,46 +581,120 @@ public class TableGenerator implements PersistentIdentifierGenerator { ); } + private IntegralDataTypeHolder nextValue( + Connection connection, + SqlStatementLogger logger, + SessionEventListenerManager listener) + throws SQLException { + final IntegralDataTypeHolder value = makeValue(); + int rows; + do { + + try ( PreparedStatement selectPS = prepareStatement( connection, selectQuery, logger, listener ) ) { + selectPS.setString( 1, segmentValue ); + final ResultSet selectRS = executeQuery( selectPS, listener ); + if ( !selectRS.next() ) { + long initializationValue; + if ( storeLastUsedValue ) { + initializationValue = initialValue - 1; + } + else { + initializationValue = initialValue; + } + value.initialize( initializationValue ); + + try ( PreparedStatement statement = prepareStatement( connection, insertQuery, logger, listener ) ) { + LOG.tracef( "binding parameter [%s] - [%s]", 1, segmentValue ); + statement.setString( 1, segmentValue ); + value.bind( statement, 2 ); + executeUpdate( statement, listener); + } + } + else { + int defaultValue; + if ( storeLastUsedValue ) { + defaultValue = 0; + } + else { + defaultValue = 1; + } + value.initialize( selectRS, defaultValue ); + } + selectRS.close(); + } + catch (SQLException e) { + LOG.unableToReadOrInitHiValue( e ); + throw e; + } + + + try ( PreparedStatement statement = prepareStatement( connection, updateQuery, logger, listener ) ) { + final IntegralDataTypeHolder updateValue = value.copy(); + if ( optimizer.applyIncrementSizeToSourceValues() ) { + updateValue.add( incrementSize ); + } + else { + updateValue.increment(); + } + updateValue.bind( statement, 1 ); + value.bind( statement, 2 ); + statement.setString( 3, segmentValue ); + rows = executeUpdate( statement, listener ); + } + catch (SQLException e) { + LOG.unableToUpdateQueryHiValue( physicalTableName.render(), e ); + throw e; + } + } + while ( rows == 0 ); + + accessCount++; + if ( storeLastUsedValue ) { + return value.increment(); + } + else { + return value; + } + } + private PreparedStatement prepareStatement( Connection connection, String sql, - SqlStatementLogger statementLogger, - SessionEventListenerManager statsCollector) throws SQLException { - statementLogger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); + SqlStatementLogger logger, + SessionEventListenerManager listener) throws SQLException { + logger.logStatement( sql, FormatStyle.BASIC.getFormatter() ); try { - statsCollector.jdbcPrepareStatementStart(); + listener.jdbcPrepareStatementStart(); return connection.prepareStatement( sql ); } finally { - statsCollector.jdbcPrepareStatementEnd(); + listener.jdbcPrepareStatementEnd(); } } - private int executeUpdate(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + private int executeUpdate(PreparedStatement ps, SessionEventListenerManager listener) throws SQLException { try { - statsCollector.jdbcExecuteStatementStart(); + listener.jdbcExecuteStatementStart(); return ps.executeUpdate(); } finally { - statsCollector.jdbcExecuteStatementEnd(); + listener.jdbcExecuteStatementEnd(); } } - private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager statsCollector) throws SQLException { + private ResultSet executeQuery(PreparedStatement ps, SessionEventListenerManager listener) throws SQLException { try { - statsCollector.jdbcExecuteStatementStart(); + listener.jdbcExecuteStatementStart(); return ps.executeQuery(); } finally { - statsCollector.jdbcExecuteStatementEnd(); + listener.jdbcExecuteStatementEnd(); } } @Override public void registerExportables(Database database) { - final Dialect dialect = database.getJdbcEnvironment().getDialect(); - final Namespace namespace = database.locateNamespace( qualifiedTableName.getCatalogName(), qualifiedTableName.getSchemaName() diff --git a/hibernate-core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java b/hibernate-core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java index cb9846d204..8a0ed6d8ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/id/factory/IdentifierGeneratorFactory.java @@ -14,7 +14,7 @@ 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.tuple.Generator; import org.hibernate.type.Type; import org.hibernate.type.descriptor.java.JavaType; @@ -50,7 +50,7 @@ public interface IdentifierGeneratorFactory extends Service { * Create an {@link IdentifierGenerator} based on the given details. */ @Incubating - InMemoryGenerator createIdentifierGenerator( + Generator createIdentifierGenerator( GenerationType generationType, String generatedValueGeneratorName, String generatorName, @@ -71,7 +71,7 @@ public interface IdentifierGeneratorFactory extends Service { * instead */ @Deprecated(since = "6.0") - InMemoryGenerator createIdentifierGenerator(String strategy, Type type, Properties parameters); + Generator createIdentifierGenerator(String strategy, Type type, Properties parameters); /** * Retrieve the class that will be used as the {@link IdentifierGenerator} for the given strategy. @@ -83,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 getIdentifierGeneratorClass(String strategy); /** * Get the dialect. diff --git a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/IdentifierGeneratorUtil.java b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/IdentifierGeneratorUtil.java index a1ac969ff4..59ca728e39 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/IdentifierGeneratorUtil.java +++ b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/IdentifierGeneratorUtil.java @@ -20,13 +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 org.hibernate.tuple.Generator; import java.util.Properties; public class IdentifierGeneratorUtil { - public static InMemoryGenerator createLegacyIdentifierGenerator( + public static Generator createLegacyIdentifierGenerator( SimpleValue simpleValue, IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, diff --git a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/StandardIdentifierGeneratorFactory.java b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/StandardIdentifierGeneratorFactory.java index 7aacfd23a3..6c0ab6043f 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/factory/internal/StandardIdentifierGeneratorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/id/factory/internal/StandardIdentifierGeneratorFactory.java @@ -21,6 +21,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.id.Assigned; +import org.hibernate.id.Configurable; import org.hibernate.id.ForeignGenerator; import org.hibernate.id.GUIDGenerator; import org.hibernate.id.IdentifierGenerator; @@ -43,7 +44,7 @@ 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.tuple.Generator; import org.hibernate.type.Type; import org.hibernate.type.descriptor.java.JavaType; @@ -61,7 +62,7 @@ public class StandardIdentifierGeneratorFactory implements IdentifierGeneratorFactory, BeanContainer.LifecycleOptions, Serializable { private final ConcurrentHashMap generatorTypeStrategyMap = new ConcurrentHashMap<>(); - private final ConcurrentHashMap> legacyGeneratorClassNameMap = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> legacyGeneratorClassNameMap = new ConcurrentHashMap<>(); private final ServiceRegistry serviceRegistry; private final BeanContainer beanContainer; @@ -169,7 +170,7 @@ public class StandardIdentifierGeneratorFactory } } - private void register(String strategy, Class generatorClass) { + private void register(String strategy, Class generatorClass) { ID_GEN_FAC_LOGGER.debugf( "Registering IdentifierGenerator strategy [%s] -> [%s]", strategy, generatorClass.getName() ); final Class previous = legacyGeneratorClassNameMap.put( strategy, generatorClass ); if ( previous != null && ID_GEN_FAC_LOGGER.isDebugEnabled() ) { @@ -208,10 +209,10 @@ public class StandardIdentifierGeneratorFactory } @Override - public InMemoryGenerator createIdentifierGenerator(String strategy, Type type, Properties parameters) { + public Generator createIdentifierGenerator(String strategy, Type type, Properties parameters) { try { - final Class clazz = getIdentifierGeneratorClass( strategy ); - final InMemoryGenerator identifierGenerator; + final Class clazz = getIdentifierGeneratorClass( strategy ); + final Generator identifierGenerator; if ( beanContainer == null || StandardGenerator.class.isAssignableFrom( clazz ) || legacyGeneratorClassNameMap.containsKey( strategy ) ) { @@ -223,8 +224,8 @@ public class StandardIdentifierGeneratorFactory .getBeanInstance(); } - if ( identifierGenerator instanceof IdentifierGenerator ) { - ( (IdentifierGenerator) identifierGenerator ).configure( type, parameters, serviceRegistry ); + if ( identifierGenerator instanceof Configurable ) { + ( (Configurable) identifierGenerator ).configure( type, parameters, serviceRegistry ); } return identifierGenerator; } @@ -245,7 +246,7 @@ public class StandardIdentifierGeneratorFactory } @Override - public Class getIdentifierGeneratorClass(String strategy) { + public Class getIdentifierGeneratorClass(String strategy) { if ( "hilo".equals( strategy ) ) { throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" ); } @@ -253,18 +254,18 @@ public class StandardIdentifierGeneratorFactory ? getDialect().getNativeIdentifierGeneratorStrategy() : strategy; - Class generatorClass = legacyGeneratorClassNameMap.get( resolvedStrategy ); + Class generatorClass = legacyGeneratorClassNameMap.get( resolvedStrategy ); if ( generatorClass != null ) { return generatorClass; } else { try { - Class clazz = + Class clazz = serviceRegistry.getService( ClassLoaderService.class ) .classForName( resolvedStrategy ); - if ( !InMemoryGenerator.class.isAssignableFrom( clazz ) ) { + if ( !Generator.class.isAssignableFrom( clazz ) ) { // in principle, this shouldn't happen, since @GenericGenerator - // constrains the type to subtypes of InMemoryGenerator + // constrains the type to subtypes of Generator throw new MappingException( clazz.getName() + " does not implement 'InMemoryGenerator'" ); } return clazz; diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java index 6a3784f27d..615e2075d4 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java @@ -51,10 +51,7 @@ public abstract class AbstractReturningDelegate implements InsertGeneratedIdenti } @Override - public final Object performInsert( - String insertSql, - SharedSessionContractImplementor session, - Binder binder) { + public final Object performInsert(String insertSql, SharedSessionContractImplementor session, Binder binder) { try { // prepare and execute the insert PreparedStatement insert = prepareStatement( insertSql, session ); diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java index fda08898c4..bbfd994bba 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java @@ -15,10 +15,13 @@ import org.hibernate.engine.jdbc.mutation.group.PreparedStatementDetails; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.engine.jdbc.spi.MutationStatementPreparer; +import org.hibernate.engine.jdbc.spi.StatementPreparer; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.PostInsertIdentityPersister; import org.hibernate.pretty.MessageHelper; +import static java.sql.Statement.NO_GENERATED_KEYS; + /** * Abstract InsertGeneratedIdentifierDelegate implementation where the * underlying strategy requires a subsequent select after the insert @@ -40,10 +43,8 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti */ protected abstract String getSelectSQL(); - protected void bindParameters( - Object entity, - PreparedStatement ps, - SharedSessionContractImplementor session) throws SQLException { + protected void bindParameters(Object entity, PreparedStatement ps, SharedSessionContractImplementor session) + throws SQLException { } /** @@ -51,16 +52,13 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti * from execution of {@link #getSelectSQL()}. * */ - protected abstract Object extractGeneratedValue( - Object entity, - ResultSet rs, - SharedSessionContractImplementor session) throws SQLException; + protected abstract Object extractGeneratedValue(Object entity, ResultSet rs, SharedSessionContractImplementor session) + throws SQLException; @Override public PreparedStatement prepareStatement(String insertSql, SharedSessionContractImplementor session) { - final JdbcCoordinator jdbcCoordinator = session.getJdbcCoordinator(); - final MutationStatementPreparer statementPreparer = jdbcCoordinator.getMutationStatementPreparer(); - return statementPreparer.prepareStatement( insertSql, PreparedStatement.NO_GENERATED_KEYS ); + final MutationStatementPreparer statementPreparer = session.getJdbcCoordinator().getMutationStatementPreparer(); + return statementPreparer.prepareStatement( insertSql, NO_GENERATED_KEYS ); } @Override @@ -81,10 +79,7 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti // the insert is complete, select the generated id... final String idSelectSql = getSelectSQL(); - final PreparedStatement idSelect = jdbcCoordinator - .getStatementPreparer() - .prepareStatement( idSelectSql ); - + final PreparedStatement idSelect = jdbcCoordinator.getStatementPreparer().prepareStatement( idSelectSql ); try { bindParameters( entity, idSelect, session ); @@ -118,12 +113,10 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti String insertSQL, SharedSessionContractImplementor session, Binder binder) { + StatementPreparer statementPreparer = session.getJdbcCoordinator().getStatementPreparer(); try { // prepare and execute the insert - PreparedStatement insert = session - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( insertSQL, PreparedStatement.NO_GENERATED_KEYS ); + PreparedStatement insert = statementPreparer.prepareStatement( insertSQL, NO_GENERATED_KEYS ); try { binder.bindValues( insert ); session.getJdbcCoordinator().getResultSetReturn().executeUpdate( insert ); @@ -145,10 +138,7 @@ public abstract class AbstractSelectingDelegate implements InsertGeneratedIdenti try { //fetch the generated id in a separate query - PreparedStatement idSelect = session - .getJdbcCoordinator() - .getStatementPreparer() - .prepareStatement( selectSQL, false ); + PreparedStatement idSelect = statementPreparer.prepareStatement( selectSQL, false ); try { bindParameters( binder.getEntity(), idSelect, session ); ResultSet rs = session.getJdbcCoordinator().getResultSetReturn().extract( idSelect ); diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java index f767548f36..51b42bc76a 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java @@ -66,10 +66,8 @@ public class BasicSelectingDelegate extends AbstractSelectingDelegate { } @Override - protected Object extractGeneratedValue( - Object entity, - ResultSet rs, - SharedSessionContractImplementor session) throws SQLException { + protected Object extractGeneratedValue(Object entity, ResultSet rs, SharedSessionContractImplementor session) + throws SQLException { return IdentifierGeneratorHelper.getGeneratedIdentity( rs, persister.getNavigableRole(), diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java index 11df319931..03a6fd419e 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java @@ -15,7 +15,6 @@ import org.hibernate.dialect.Dialect; import org.hibernate.dialect.identity.IdentityColumnSupport; import org.hibernate.engine.jdbc.spi.JdbcCoordinator; import org.hibernate.engine.jdbc.spi.JdbcServices; -import org.hibernate.engine.jdbc.spi.MutationStatementPreparer; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.IdentifierGeneratorHelper; @@ -24,6 +23,8 @@ import org.hibernate.jdbc.Expectation; import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; import org.hibernate.sql.model.ast.builder.TableInsertBuilder; +import static java.sql.Statement.NO_GENERATED_KEYS; + /** * Delegate for dealing with IDENTITY columns where the dialect supports returning * the generated IDENTITY value directly from the insert statement. @@ -97,10 +98,6 @@ public class InsertReturningDelegate extends AbstractReturningDelegate { @Override public PreparedStatement prepareStatement(String insertSql, SharedSessionContractImplementor session) { - final MutationStatementPreparer statementPreparer = session - .getJdbcCoordinator() - .getMutationStatementPreparer(); - - return statementPreparer.prepareStatement( insertSql, PreparedStatement.NO_GENERATED_KEYS ); + return session.getJdbcCoordinator().getMutationStatementPreparer().prepareStatement( insertSql, NO_GENERATED_KEYS ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java index d97c919914..a7f9863315 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java @@ -28,6 +28,7 @@ public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert { } public String toStatementString() { - return getDialect().getIdentityColumnSupport().appendIdentitySelectToInsert( identityColumnName, super.toStatementString() ); + return getDialect().getIdentityColumnSupport() + .appendIdentitySelectToInsert( identityColumnName, super.toStatementString() ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index ebe08ad813..c13e485587 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -124,7 +124,7 @@ import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory; import org.hibernate.stat.spi.StatisticsImplementor; import org.hibernate.tool.schema.spi.DelayedDropAction; import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.Type; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.spi.TypeConfiguration; @@ -184,7 +184,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { private volatile DelayedDropAction delayedDropAction; // todo : move to MetamodelImpl - private final transient Map identifierGenerators; + private final transient Map identifierGenerators; private final transient Map filters; private final transient Map fetchProfiles; @@ -294,7 +294,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { //Generators: this.identifierGenerators = new HashMap<>(); bootMetamodel.getEntityBindings().stream().filter( model -> !model.isInherited() ).forEach( model -> { - final InMemoryGenerator generator = model.getIdentifier().createGenerator( + final Generator generator = model.getIdentifier().createGenerator( bootstrapContext.getIdentifierGeneratorFactory(), jdbcServices.getJdbcEnvironment().getDialect(), (RootClass) model @@ -994,7 +994,7 @@ public class SessionFactoryImpl implements SessionFactoryImplementor { } @Deprecated - public InMemoryGenerator getGenerator(String rootEntityName) { + public Generator getGenerator(String rootEntityName) { return identifierGenerators.get( rootEntityName ); } diff --git a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java index 2fc5f0ea0a..8e1faf44b9 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/StatelessSessionImpl.java @@ -28,12 +28,13 @@ import org.hibernate.engine.spi.PersistentAttributeInterceptor; import org.hibernate.engine.transaction.internal.jta.JtaStatusHelper; import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; import org.hibernate.event.spi.EventSource; -import org.hibernate.id.IdentifierGeneratorHelper; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.EntityPersister; import org.hibernate.pretty.MessageHelper; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; +import org.hibernate.tuple.Generator; +import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.tuple.entity.EntityMetamodel; import jakarta.transaction.SystemException; @@ -94,25 +95,27 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen @Override public Object insert(String entityName, Object entity) { checkOpen(); - EntityPersister persister = getEntityPersister( entityName, entity ); - Object id = persister.getGenerator().generate( this, entity, null ); - Object[] state = persister.getValues( entity ); - if ( persister.isVersioned() ) { - boolean substitute = Versioning.seedVersion( - state, - persister.getVersionProperty(), - persister.getVersionMapping(), - this - ); - if ( substitute ) { - persister.setValues( entity, state ); + final EntityPersister persister = getEntityPersister( entityName, entity ); + final Object id; + final Object[] state = persister.getValues( entity ); + Generator generator = persister.getGenerator(); + if ( !generator.generatedByDatabase() ) { + id = ( (InMemoryGenerator) generator).generate( this, entity, null ); + if ( persister.isVersioned() ) { + boolean substitute = Versioning.seedVersion( + state, + persister.getVersionProperty(), + persister.getVersionMapping(), + this + ); + if ( substitute ) { + persister.setValues( entity, state ); + } } - } - if ( id == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) { - id = persister.insert( state, entity, this ); + persister.insert( id, state, entity, this ); } else { - persister.insert( id, state, entity, this ); + id = persister.insert( state, entity, this ); } persister.setIdentifier( entity, id, this ); return id; diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java index e53ac8ca21..c7663f33db 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Component.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Component.java @@ -28,12 +28,14 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.CompositeNestedGeneratedValueGenerator; import org.hibernate.id.IdentifierGenerator; +import org.hibernate.id.IdentifierGeneratorHelper; import org.hibernate.id.factory.IdentifierGeneratorFactory; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.JoinedIterator; import org.hibernate.metamodel.spi.EmbeddableInstantiator; import org.hibernate.property.access.spi.Setter; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.ComponentType; import org.hibernate.type.EmbeddedComponentType; @@ -72,7 +74,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable // lazily computed based on 'properties' field: invalidate by setting to null when properties are modified private transient List cachedColumns; - private transient InMemoryGenerator builtIdentifierGenerator; + private transient Generator builtIdentifierGenerator; public Component(MetadataBuildingContext metadata, PersistentClass owner) throws MappingException { this( metadata, owner.getTable(), owner ); @@ -414,7 +416,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable } @Override - public InMemoryGenerator createGenerator( + public Generator createGenerator( IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, RootClass rootClass) throws MappingException { @@ -428,7 +430,7 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable return builtIdentifierGenerator; } - private InMemoryGenerator buildIdentifierGenerator( + private Generator buildIdentifierGenerator( IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, RootClass rootClass) throws MappingException { @@ -470,11 +472,10 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable if ( !DEFAULT_ID_GEN_STRATEGY.equals( value.getIdentifierGeneratorStrategy() ) ) { // skip any 'assigned' generators, they would have been handled by // the StandardGenerationContextLocator - generator.addGeneratedValuePlan( - new ValueGenerationPlan( - value.createGenerator( identifierGeneratorFactory, dialect, rootClass ), - injector( property, attributeDeclarer ) - ) + Generator subgenerator = value.createGenerator( identifierGeneratorFactory, dialect, rootClass ); + generator.addGeneratedValuePlan( new ValueGenerationPlan( + subgenerator, + injector( property, attributeDeclarer ) ) ); } } @@ -512,11 +513,11 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable } public static class ValueGenerationPlan implements CompositeNestedGeneratedValueGenerator.GenerationPlan { - private final InMemoryGenerator subGenerator; + private final Generator subGenerator; private final Setter injector; public ValueGenerationPlan( - InMemoryGenerator subGenerator, + Generator subGenerator, Setter injector) { this.subGenerator = subGenerator; this.injector = injector; @@ -524,7 +525,13 @@ public class Component extends SimpleValue implements MetaAttributable, Sortable @Override public void execute(SharedSessionContractImplementor session, Object incomingObject, Object injectionContext) { - injector.set( injectionContext, subGenerator.generate( session, incomingObject, null ) ); + if ( !subGenerator.generatedByDatabase() ) { + Object generatedId = ( (InMemoryGenerator) subGenerator ).generate( session, incomingObject, null ); + injector.set( injectionContext, generatedId ); + } + else { + injector.set( injectionContext, IdentifierGeneratorHelper.POST_INSERT_INDICATOR ); + } } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java index cc5f913003..679bd4b99a 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java @@ -9,6 +9,7 @@ package org.hibernate.mapping; import org.hibernate.dialect.Dialect; import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.factory.IdentifierGeneratorFactory; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; /** @@ -29,7 +30,7 @@ public interface KeyValue extends Value { boolean isUpdateable(); - InMemoryGenerator createGenerator( + Generator createGenerator( IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, RootClass rootClass); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index f05f86838d..151ac27bb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -47,7 +47,7 @@ import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter; import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.service.ServiceRegistry; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.Type; import org.hibernate.type.descriptor.JdbcTypeNameMapper; import org.hibernate.type.descriptor.java.JavaType; @@ -101,8 +101,7 @@ public abstract class SimpleValue implements KeyValue { private Type type; private IdentifierGeneratorCreator customIdGeneratorCreator; - private GeneratorCreator customGeneratorCreator; - private InMemoryGenerator generator; + private Generator generator; public SimpleValue(MetadataBuildingContext buildingContext) { this.buildingContext = buildingContext; @@ -379,41 +378,24 @@ public abstract class SimpleValue implements KeyValue { return customIdGeneratorCreator; } - public GeneratorCreator getCustomGeneratorCreator() { - return customGeneratorCreator; - } - - public void setCustomGeneratorCreator(GeneratorCreator customGeneratorCreator) { - this.customGeneratorCreator = customGeneratorCreator; - } - @Override - public InMemoryGenerator createGenerator( + public Generator createGenerator( IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect, RootClass rootClass) throws MappingException { if ( generator != null ) { return generator; } - - if ( customIdGeneratorCreator != null ) { + else if ( customIdGeneratorCreator != null ) { generator = customIdGeneratorCreator.createGenerator( new IdGeneratorCreationContext( identifierGeneratorFactory, null, null, rootClass ) ); return generator; } - else if ( customGeneratorCreator != null ) { - // we may as well allow this, so you don't have to annotate generator - // annotations twice, with @IdGeneratorType and @ValueGenerationType - //TODO: this typecast is ugly ... throw a better exception at least - generator = (InMemoryGenerator) customGeneratorCreator.createGenerator( - new IdGeneratorCreationContext( identifierGeneratorFactory, null, null, rootClass ) - ); + else { + generator = createLegacyIdentifierGenerator(this, identifierGeneratorFactory, dialect, null, null, rootClass ); return generator; } - - generator = createLegacyIdentifierGenerator(this, identifierGeneratorFactory, dialect, null, null, rootClass ); - return generator; } public boolean isUpdateable() { diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index ed74da58ce..16f8949dc8 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -128,6 +128,7 @@ import org.hibernate.sql.model.jdbc.JdbcDeleteMutation; import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.internal.SqlSelectionImpl; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.CollectionType; import org.hibernate.type.CompositeType; @@ -510,14 +511,7 @@ public abstract class AbstractCollectionPersister Column col = idColl.getIdentifier().getColumns().get(0); identifierColumnName = col.getQuotedName( dialect ); identifierColumnAlias = col.getAlias( dialect ); - identifierGenerator = idColl.getIdentifier().createGenerator( - creationContext.getBootstrapContext().getIdentifierGeneratorFactory(), - factory.getJdbcServices().getDialect(), - null - ); - if ( identifierGenerator instanceof IdentifierGenerator ) { - ( (IdentifierGenerator) identifierGenerator ).initialize( creationContext.getSessionFactory().getSqlStringGenerationContext() ); - } + identifierGenerator = createGenerator( creationContext, idColl ); } else { identifierType = null; @@ -629,6 +623,21 @@ public abstract class AbstractCollectionPersister tableMapping = buildCollectionTableMapping( collectionBootDescriptor, qualifiedTableName ); } + private InMemoryGenerator createGenerator(RuntimeModelCreationContext context, IdentifierCollection collection) { + final Generator generator = collection.getIdentifier().createGenerator( + context.getBootstrapContext().getIdentifierGeneratorFactory(), + factory.getJdbcServices().getDialect(), + null + ); + if ( generator.generatedByDatabase() ) { + throw new MappingException("must be an InMemoryGenerator"); //TODO fix message + } + if ( generator instanceof IdentifierGenerator ) { + ( (IdentifierGenerator) generator ).initialize( context.getSessionFactory().getSqlStringGenerationContext() ); + } + return (InMemoryGenerator) generator; + } + @Override public NavigableRole getNavigableRole() { return navigableRole; diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 67e0c3e4de..6ca9b52704 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -2773,8 +2773,8 @@ public abstract class AbstractEntityPersister && generator.getGenerationTiming().includesUpdate() && generator.generatedByDatabase() ) { final InDatabaseGenerator databaseGenerator = (InDatabaseGenerator) generator; - if ( databaseGenerator.referenceColumnsInSql() ) { - final Dialect dialect = getFactory().getJdbcServices().getDialect(); + final Dialect dialect = getFactory().getJdbcServices().getDialect(); + if ( databaseGenerator.referenceColumnsInSql(dialect) ) { update.addColumns( getPropertyColumnNames(index), SINGLE_TRUE, @@ -3179,7 +3179,7 @@ public abstract class AbstractEntityPersister private void doLateInit() { if ( isIdentifierAssignedByInsert() ) { - final PostInsertIdentifierGenerator idGenerator = (PostInsertIdentifierGenerator) getIdentifierGenerator(); + final PostInsertIdentifierGenerator idGenerator = (PostInsertIdentifierGenerator) getGenerator(); identityDelegate = idGenerator.getInsertGeneratedIdentifierDelegate( this, getFactory().getJdbcServices().getDialect(), @@ -3944,7 +3944,7 @@ public abstract class AbstractEntityPersister } @Override - public InMemoryGenerator getGenerator() { + public Generator getGenerator() { return entityMetamodel.getIdentifierProperty().getGenerator(); } @@ -4344,7 +4344,7 @@ public abstract class AbstractEntityPersister Object currentId, Object currentVersion, SharedSessionContractImplementor session) { - if ( entityMetamodel.getIdentifierProperty().getIdentifierGenerator() instanceof Assigned ) { + if ( entityMetamodel.getIdentifierProperty().getGenerator() instanceof Assigned ) { return; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java index 3959fdb7ba..4d1b83cf71 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/EntityPersister.java @@ -45,7 +45,7 @@ import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.sql.ast.spi.SqlAliasStemHelper; import org.hibernate.sql.ast.tree.from.RootTableGroupProducer; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.type.BasicType; import org.hibernate.type.Type; @@ -459,7 +459,7 @@ public interface EntityPersister @Deprecated IdentifierGenerator getIdentifierGenerator(); - default InMemoryGenerator getGenerator() { + default Generator getGenerator() { return getIdentifierGenerator(); } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java index c42ad5cb21..b1c75b7c20 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/AbstractMutationCoordinator.java @@ -51,6 +51,11 @@ public abstract class AbstractMutationCoordinator { return factory; } + protected Dialect dialect() { + return factory().getJdbcServices().getDialect(); + } + + protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnalysis, MutationGroup mutationGroup) { if ( mutationGroup.getNumberOfTableMutations() == 0 ) { return new MutationOperationGroupNone( mutationGroup.getMutationType(), mutationGroup.getMutationTarget() ); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java index df1797b97e..2ee719eb62 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/InsertCoordinator.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; import org.hibernate.Internal; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; import org.hibernate.engine.jdbc.mutation.MutationExecutor; @@ -106,7 +107,7 @@ public class InsertCoordinator extends AbstractMutationCoordinator { if ( generator != null && !generator.generatedByDatabase() && generator.getGenerationTiming().includesInsert() ) { - values[i] = ( (InMemoryGenerator) generator).generate( session, entity, values[i] ); + values[i] = ( (InMemoryGenerator) generator ).generate( session, entity, values[i] ); entityPersister().setPropertyValue( entity, i, values[i] ); } } @@ -393,7 +394,7 @@ public class InsertCoordinator extends AbstractMutationCoordinator { if ( !attributeInclusions[ attributeIndex ] ) { final Generator generator = attributeMapping.getGenerator(); - if ( isValueGenerationInSql( generator ) ) { + if ( isValueGenerationInSql( generator, factory().getJdbcServices().getDialect()) ) { handleValueGeneration( attributeMapping, insertGroupBuilder, (InDatabaseGenerator) generator ); } continue; @@ -435,10 +436,10 @@ public class InsertCoordinator extends AbstractMutationCoordinator { } ); } - private static boolean isValueGenerationInSql(Generator generator) { + private static boolean isValueGenerationInSql(Generator generator, Dialect dialect) { return generator != null && generator.getGenerationTiming().includesInsert() && generator.generatedByDatabase() - && ( (InDatabaseGenerator) generator ).referenceColumnsInSql(); + && ( (InDatabaseGenerator) generator ).referenceColumnsInSql(dialect); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java index 4cdb44bced..6868553344 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/mutation/UpdateCoordinatorStandard.java @@ -14,6 +14,7 @@ import java.util.Set; import org.hibernate.HibernateException; import org.hibernate.Internal; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey; import org.hibernate.engine.jdbc.batch.spi.BatchKey; @@ -200,8 +201,10 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple } } + final InclusionChecker updateabilityChecker = - (position, attribute) -> isValueGenerationInSql( attribute.getGenerator() ) || attributeUpdateability[ position ]; + (position, attribute) -> isValueGenerationInSql( attribute.getGenerator(), dialect() ) + || attributeUpdateability[ position ]; final InclusionChecker dirtinessChecker = (position, attribute) -> { if ( !attributeUpdateability[ position ] ) { @@ -332,18 +335,18 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple return false; } - private boolean isValueGenerationInSql(Generator generator) { + private boolean isValueGenerationInSql(Generator generator, Dialect dialect) { return generator != null && generator.getGenerationTiming().includesUpdate() && generator.generatedByDatabase() - && ((InDatabaseGenerator) generator).referenceColumnsInSql(); + && ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect); } - private boolean isValueGenerationInSqlNoWrite(Generator generator) { + private boolean isValueGenerationInSqlNoWrite(Generator generator, Dialect dialect) { return generator != null && generator.getGenerationTiming().includesUpdate() && generator.generatedByDatabase() - && ((InDatabaseGenerator) generator).referenceColumnsInSql() + && ((InDatabaseGenerator) generator).referenceColumnsInSql(dialect) && !((InDatabaseGenerator) generator).writePropertyValue(); } @@ -696,7 +699,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple // apply the new values final boolean includeInSet; - if ( isValueGenerationInSqlNoWrite( attributeMapping.getGenerator() ) ) { + if ( isValueGenerationInSqlNoWrite( attributeMapping.getGenerator(), dialect() ) ) { // we applied `#getDatabaseGeneratedReferencedColumnValue` earlier includeInSet = false; } @@ -930,7 +933,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple assert updateValuesAnalysis.tablesNeedingUpdate.contains( tableMapping ); final Generator generator = attributeMapping.getGenerator(); - if ( isValueGenerationInSql( generator ) ) { + if ( isValueGenerationInSql( generator, dialect() ) ) { handleValueGeneration( attributeMapping, updateGroupBuilder, (InDatabaseGenerator) generator ); } else if ( versionMapping != null @@ -1360,7 +1363,7 @@ public class UpdateCoordinatorStandard extends AbstractMutationCoordinator imple null, null, null, - (index,attribute) -> isValueGenerationInSql( attribute.getGenerator() ) + (index,attribute) -> isValueGenerationInSql( attribute.getGenerator(), dialect() ) || entityPersister().getPropertyUpdateability()[index], (index,attribute) -> { final OptimisticLockStyle optimisticLockStyle = entityPersister().optimisticLockStyle(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java index d6c267ef2c..3696f38305 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/internal/QuerySqmImpl.java @@ -107,6 +107,7 @@ import org.hibernate.query.sqm.tree.update.SqmAssignment; import org.hibernate.query.sqm.tree.update.SqmUpdateStatement; import org.hibernate.sql.results.internal.TupleMetadata; import org.hibernate.sql.results.spi.ListResultsConsumer; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import static org.hibernate.jpa.HibernateHints.HINT_CACHEABLE; @@ -838,7 +839,7 @@ public class QuerySqmImpl boolean useMultiTableInsert = entityDescriptor.isMultiTable(); if ( !useMultiTableInsert && !isSimpleValuesInsert( sqmInsert, entityDescriptor ) ) { - final InMemoryGenerator identifierGenerator = entityDescriptor.getGenerator(); + final Generator identifierGenerator = entityDescriptor.getGenerator(); if ( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator && identifierGenerator instanceof OptimizableGenerator ) { final Optimizer optimizer = ( (OptimizableGenerator) identifierGenerator ).getOptimizer(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java index 84f1906cec..6616d1f164 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/cte/CteInsertHandler.java @@ -94,7 +94,7 @@ import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.basic.BasicResult; import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; -import org.hibernate.tuple.InMemoryGenerator; +import org.hibernate.tuple.Generator; import org.hibernate.type.spi.TypeConfiguration; /** @@ -273,7 +273,7 @@ public class CteInsertHandler implements InsertHandler { rowNumberColumn ); } - if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) { + if ( !assignsId && entityDescriptor.getGenerator().generatedByDatabase() ) { querySpec.getSelectClause().addSqlSelection( new SqlSelectionImpl( 1, @@ -337,7 +337,7 @@ public class CteInsertHandler implements InsertHandler { processingStateStack.push( oldState ); sqmConverter.pruneTableGroupJoins(); - if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) { + if ( !assignsId && entityDescriptor.getGenerator().generatedByDatabase() ) { // Add the row number to the assignments final CteColumn rowNumberColumn = cteTable.getCteColumns() .get( cteTable.getCteColumns().size() - 1 ); @@ -581,7 +581,7 @@ public class CteInsertHandler implements InsertHandler { statement.addCteStatement( entityCte ); } } - else if ( !assignsId && entityDescriptor.getGenerator() instanceof PostInsertIdentifierGenerator ) { + else if ( !assignsId && entityDescriptor.getGenerator().generatedByDatabase() ) { final String baseTableName = "base_" + entityCteTable.getTableExpression(); final CteStatement baseEntityCte = new CteStatement( entityCteTable.withName( baseTableName ), @@ -775,9 +775,10 @@ public class CteInsertHandler implements InsertHandler { true ); - final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator(); + final Generator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator(); final List, Assignment>> tableAssignments = assignmentsByTable.get( rootTableReference ); - if ( ( tableAssignments == null || tableAssignments.isEmpty() ) && !( identifierGenerator instanceof PostInsertIdentifierGenerator ) ) { + if ( ( tableAssignments == null || tableAssignments.isEmpty() ) + && !( identifierGenerator.generatedByDatabase() ) ) { throw new IllegalStateException( "There must be at least a single root table assignment" ); } @@ -805,7 +806,7 @@ public class CteInsertHandler implements InsertHandler { final QuerySpec insertSelectSpec = new QuerySpec( true ); CteStatement finalCteStatement = null; final CteTable dmlResultCte; - if ( i == 0 && !assignsId && identifierGenerator instanceof PostInsertIdentifierGenerator ) { + if ( i == 0 && !assignsId && identifierGenerator.generatedByDatabase() ) { // Special handling for identity generation final String cteTableName = getCteTableName( tableExpression, "base_" ); if ( statement.getCteStatement( cteTableName ) != null ) { @@ -1074,7 +1075,7 @@ public class CteInsertHandler implements InsertHandler { if ( finalCteStatement != null ) { statement.addCteStatement( finalCteStatement ); } - if ( i == 0 && !assignsId && identifierGenerator instanceof PostInsertIdentifierGenerator ) { + if ( i == 0 && !assignsId && identifierGenerator.generatedByDatabase() ) { // Special handling for identity generation statement.addCteStatement( queryCte ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java index 3738a67431..a8080a0618 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/InsertExecutionDelegate.java @@ -73,6 +73,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.results.graph.basic.BasicFetch; import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.sql.results.spi.ListResultsConsumer; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.descriptor.ValueBinder; @@ -301,12 +302,12 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio true ); - final InMemoryGenerator identifierGenerator = entityDescriptor.getEntityPersister().getGenerator(); + final Generator generator = entityDescriptor.getEntityPersister().getGenerator(); final List assignments = assignmentsByTable.get( updatingTableReference ); if ( ( assignments == null || assignments.isEmpty() ) - && !( identifierGenerator instanceof PostInsertIdentifierGenerator ) - && ( !( identifierGenerator instanceof BulkInsertionCapableIdentifierGenerator ) - || ( (BulkInsertionCapableIdentifierGenerator) identifierGenerator ).supportsBulkInsertionIdentifierGeneration() ) ) { + && !generator.generatedByDatabase() + && ( !( generator instanceof BulkInsertionCapableIdentifierGenerator ) + || ( (BulkInsertionCapableIdentifierGenerator) generator ).supportsBulkInsertionIdentifierGeneration() ) ) { throw new IllegalStateException( "There must be at least a single root table assignment" ); } @@ -352,7 +353,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio } final JdbcServices jdbcServices = sessionFactory.getJdbcServices(); final Map entityTableToRootIdentity; - if ( identifierGenerator instanceof PostInsertIdentifierGenerator ) { + if ( generator.generatedByDatabase() ) { final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping(); final QuerySpec idSelectQuerySpec = new QuerySpec( true ); idSelectQuerySpec.getFromClause().addRoot( temporaryTableGroup ); @@ -413,10 +414,9 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio // if the target paths don't already contain the id, and we need identifier generation, // then we load update rows from the temporary table with the generated identifiers, // to then insert into the target tables in once statement - if ( needsIdentifierGeneration( identifierGenerator ) - && insertStatement.getTargetColumns() - .stream() - .noneMatch( c -> keyColumns[0].equals( c.getColumnExpression() ) ) ) { + if ( needsIdentifierGeneration( generator ) + && insertStatement.getTargetColumns().stream() + .noneMatch( c -> keyColumns[0].equals( c.getColumnExpression() ) ) ) { final BasicEntityIdentifierMapping identifierMapping = (BasicEntityIdentifierMapping) entityDescriptor.getIdentifierMapping(); final JdbcParameter rowNumber = new JdbcParameterImpl( identifierMapping.getJdbcMapping() ); @@ -507,7 +507,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio rootIdentity, new JdbcParameterBindingImpl( identifierMapping.getJdbcMapping(), - identifierGenerator.generate( executionContext.getSession(), null, null ) + ( (InMemoryGenerator) generator ).generate( executionContext.getSession(), null, null ) ) ); jdbcServices.getJdbcMutationExecutor().execute( @@ -555,10 +555,10 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio .buildInsertTranslator( sessionFactory, insertStatement ) .translate( null, executionContext.getQueryOptions() ); - if ( identifierGenerator instanceof PostInsertIdentifierGenerator ) { - final PostInsertIdentifierGenerator generator = (PostInsertIdentifierGenerator) identifierGenerator; + if ( generator.generatedByDatabase() ) { + final PostInsertIdentifierGenerator postInsertGenerator = (PostInsertIdentifierGenerator) generator; final boolean generatedKeysEnabled = sessionFactory.getSessionFactoryOptions().isGetGeneratedKeysEnabled(); - final InsertGeneratedIdentifierDelegate identifierDelegate = generator.getInsertGeneratedIdentifierDelegate( + final InsertGeneratedIdentifierDelegate identifierDelegate = postInsertGenerator.getInsertGeneratedIdentifierDelegate( (PostInsertIdentityPersister) entityDescriptor.getEntityPersister(), jdbcServices.getDialect(), generatedKeysEnabled @@ -651,7 +651,7 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio } } - private boolean needsIdentifierGeneration(InMemoryGenerator identifierGenerator) { + private boolean needsIdentifierGeneration(Generator identifierGenerator) { if ( !( identifierGenerator instanceof OptimizableGenerator ) ) { return false; } @@ -718,9 +718,9 @@ public class InsertExecutionDelegate implements TableBasedInsertHandler.Executio } final String targetKeyColumnName = keyColumns[0]; final AbstractEntityPersister entityPersister = (AbstractEntityPersister) entityDescriptor.getEntityPersister(); - final InMemoryGenerator identifierGenerator = entityPersister.getGenerator(); + final Generator identifierGenerator = entityPersister.getGenerator(); final boolean needsKeyInsert; - if ( identifierGenerator instanceof PostInsertIdentifierGenerator ) { + if ( identifierGenerator.generatedByDatabase() ) { needsKeyInsert = true; } else if ( identifierGenerator instanceof OptimizableGenerator ) { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java index cfbf100251..cae7e3cba5 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedInsertHandler.java @@ -52,6 +52,7 @@ import org.hibernate.sql.ast.tree.update.Assignment; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.results.internal.SqlSelectionImpl; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.BasicType; @@ -254,7 +255,7 @@ public class TableBasedInsertHandler implements InsertHandler { } else { // Add the row number column if there is one - final InMemoryGenerator generator = entityDescriptor.getGenerator(); + final Generator generator = entityDescriptor.getGenerator(); final BasicType rowNumberType; if ( generator instanceof OptimizableGenerator ) { final Optimizer optimizer = ( (OptimizableGenerator) generator ).getOptimizer(); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index 4e4a714fc3..544912548b 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -45,7 +45,6 @@ import org.hibernate.graph.spi.AppliedGraph; import org.hibernate.id.BulkInsertionCapableIdentifierGenerator; import org.hibernate.id.CompositeNestedGeneratedValueGenerator; import org.hibernate.id.OptimizableGenerator; -import org.hibernate.id.PostInsertIdentifierGenerator; import org.hibernate.id.enhanced.Optimizer; import org.hibernate.internal.FilterHelper; import org.hibernate.internal.util.collections.CollectionHelper; @@ -383,6 +382,7 @@ import org.hibernate.sql.results.graph.FetchableContainer; import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation; import org.hibernate.sql.results.internal.SqlSelectionImpl; import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl; +import org.hibernate.tuple.Generator; import org.hibernate.tuple.InMemoryGenerator; import org.hibernate.type.BasicType; import org.hibernate.type.CustomType; @@ -1230,7 +1230,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base BasicEntityIdentifierMapping identifierMapping = null; // We use the id property name to null the identifier generator variable if the target paths contain the id final String identifierPropertyName; - InMemoryGenerator identifierGenerator = entityDescriptor.getGenerator(); + Generator identifierGenerator = entityDescriptor.getGenerator(); identifierPropertyName = identifierGenerator != null ? entityDescriptor.getIdentifierPropertyName() : null; final String versionAttributeName; boolean needsVersionInsert; @@ -1287,7 +1287,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base } // This uses identity generation, so we don't need to list the column - if ( identifierGenerator instanceof PostInsertIdentifierGenerator + if ( identifierGenerator != null && identifierGenerator.generatedByDatabase() || identifierGenerator instanceof CompositeNestedGeneratedValueGenerator ) { identifierGenerator = null; } @@ -1346,7 +1346,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base public static class AdditionalInsertValues { private final Expression versionExpression; private final Expression discriminatorExpression; - private final InMemoryGenerator identifierGenerator; + private final Generator identifierGenerator; private final BasicEntityIdentifierMapping identifierMapping; private Expression identifierGeneratorParameter; private SqlSelection versionSelection; @@ -1356,7 +1356,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base public AdditionalInsertValues( Expression versionExpression, Expression discriminatorExpression, - InMemoryGenerator identifierGenerator, + Generator identifierGenerator, BasicEntityIdentifierMapping identifierMapping) { this.versionExpression = versionExpression; this.discriminatorExpression = discriminatorExpression; @@ -1372,9 +1372,10 @@ public abstract class BaseSqmToSqlAstConverter extends Base if ( discriminatorExpression != null ) { expressions.add( discriminatorExpression ); } - if ( identifierGenerator != null ) { + if ( identifierGenerator != null && !identifierGenerator.generatedByDatabase() ) { if ( identifierGeneratorParameter == null ) { - identifierGeneratorParameter = new IdGeneratorParameter( identifierMapping, identifierGenerator ); + identifierGeneratorParameter = + new IdGeneratorParameter( identifierMapping, (InMemoryGenerator) identifierGenerator ); } expressions.add( identifierGeneratorParameter ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java index c96de2ad06..cb3c6c43f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedAlwaysValueGeneration.java @@ -30,7 +30,7 @@ public class GeneratedAlwaysValueGeneration } @Override - public boolean referenceColumnsInSql() { + public boolean referenceColumnsInSql(Dialect dialect) { return false; } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java index ea5446b8ac..0e76fbbd70 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/GeneratedValueGeneration.java @@ -46,7 +46,7 @@ public class GeneratedValueGeneration implements InDatabaseGenerator { } @Override - public boolean referenceColumnsInSql() { + public boolean referenceColumnsInSql(Dialect dialect) { return writable; } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java index 854ebacadc..510ca17f47 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierAttribute.java @@ -19,7 +19,7 @@ public interface IdentifierAttribute extends Attribute { @Deprecated IdentifierGenerator getIdentifierGenerator(); - InMemoryGenerator getGenerator(); + Generator getGenerator(); boolean isIdentifierAssignedByInsert(); diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java index c35071f883..4311336fb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/IdentifierProperty.java @@ -20,7 +20,7 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA private final boolean virtual; private final boolean embedded; - private final InMemoryGenerator identifierGenerator; + private final Generator identifierGenerator; private final boolean identifierAssignedByInsert; private final boolean hasIdentifierMapper; @@ -38,13 +38,13 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA String name, Type type, boolean embedded, - InMemoryGenerator identifierGenerator) { + Generator identifierGenerator) { super( name, type ); this.virtual = false; this.embedded = embedded; this.hasIdentifierMapper = false; this.identifierGenerator = identifierGenerator; - this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator; + this.identifierAssignedByInsert = identifierGenerator.generatedByDatabase(); } /** @@ -59,13 +59,13 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA Type type, boolean embedded, boolean hasIdentifierMapper, - InMemoryGenerator identifierGenerator) { + Generator identifierGenerator) { super( null, type ); this.virtual = true; this.embedded = embedded; this.hasIdentifierMapper = hasIdentifierMapper; this.identifierGenerator = identifierGenerator; - this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator; + this.identifierAssignedByInsert = identifierGenerator.generatedByDatabase(); } @Override @@ -84,7 +84,7 @@ public class IdentifierProperty extends AbstractAttribute implements IdentifierA } @Override - public InMemoryGenerator getGenerator() { + public Generator getGenerator() { return identifierGenerator; } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseGenerator.java b/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseGenerator.java index 016a80d749..da4c32ab62 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/InDatabaseGenerator.java @@ -15,7 +15,7 @@ import org.hibernate.dialect.Dialect; * statement. In this case, the generated value is retrieved from the database using a SQL * {@code select}. *

- * Implementations should override {@link #referenceColumnsInSql()}, + * Implementations should override {@link #referenceColumnsInSql(Dialect)}, * {@link #writePropertyValue()}, and {@link #getReferencedColumnValues(Dialect)} as needed * in order to achieve the desired behavior. * @@ -39,7 +39,7 @@ public interface InDatabaseGenerator extends Generator { * * @return {@code true} if the column is included in the column list of the SQL statement. */ - boolean referenceColumnsInSql(); + boolean referenceColumnsInSql(Dialect dialect); /** * Determines if the property values are written to JDBC as the argument of a JDBC {@code ?} @@ -49,8 +49,8 @@ public interface InDatabaseGenerator extends Generator { /** * A SQL expression indicating how to calculate the generated values when the mapped columns - * are {@linkplain #referenceColumnsInSql() included in the SQL statement}. The SQL expressions - * might be: + * are {@linkplain #referenceColumnsInSql(Dialect) included in the SQL statement}. The SQL + * expressions might be: *