From 0f4cdc3bdb3b2cff5e16467f256af534febe165b Mon Sep 17 00:00:00 2001 From: Gavin Date: Mon, 19 Dec 2022 20:02:13 +0100 Subject: [PATCH] use getGeneratedKeys() in SelectGenerator on Oracle --- .../java/org/hibernate/dialect/Dialect.java | 3 +++ .../org/hibernate/dialect/OracleDialect.java | 6 ++++- .../identity/IdentityColumnSupportImpl.java | 2 +- .../Oracle12cGetGeneratedKeysDelegate.java | 26 ++++--------------- .../Oracle12cIdentityColumnSupport.java | 2 +- .../org/hibernate/id/SelectGenerator.java | 9 ++++--- .../id/insert/GetGeneratedKeysDelegate.java | 11 +++++--- 7 files changed, 28 insertions(+), 31 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 159da4815e..49f33501fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -3448,6 +3448,9 @@ public abstract class Dialect implements ConversionContext { return false; } + public boolean supportedInsertReturningGeneratedKeys() { + return false; + } /** * Does this dialect support the given fetch clause type. * diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java index 27f6946e62..bf210199a7 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleDialect.java @@ -323,6 +323,10 @@ public class OracleDialect extends Dialect { return "current_timestamp"; } + @Override + public boolean supportedInsertReturningGeneratedKeys() { + return true; + } /** * Oracle doesn't have any sort of {@link Types#BOOLEAN} @@ -423,7 +427,7 @@ public class OracleDialect extends Dialect { * Oracle supports a limited list of temporal fields in the * extract() function, but we can emulate some of them by * using to_char() with a format string instead of extract(). - * + *

* Thus, the additional supported fields are * {@link TemporalUnit#DAY_OF_YEAR}, * {@link TemporalUnit#DAY_OF_MONTH}, diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupportImpl.java b/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupportImpl.java index 8111bcdfd0..fe2e75b348 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupportImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/identity/IdentityColumnSupportImpl.java @@ -55,6 +55,6 @@ public class IdentityColumnSupportImpl implements IdentityColumnSupport { public GetGeneratedKeysDelegate buildGetGeneratedKeysDelegate( PostInsertIdentityPersister persister, Dialect dialect) { - return new GetGeneratedKeysDelegate( persister, dialect ); + return new GetGeneratedKeysDelegate( persister, dialect, true ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cGetGeneratedKeysDelegate.java b/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cGetGeneratedKeysDelegate.java index 79c3674aba..3883613ca3 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cGetGeneratedKeysDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cGetGeneratedKeysDelegate.java @@ -6,35 +6,19 @@ */ package org.hibernate.dialect.identity; -import java.sql.PreparedStatement; - -import org.hibernate.HibernateException; +import org.hibernate.Remove; import org.hibernate.dialect.Dialect; -import org.hibernate.engine.jdbc.spi.JdbcCoordinator; -import org.hibernate.engine.jdbc.spi.MutationStatementPreparer; -import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.PostInsertIdentityPersister; import org.hibernate.id.insert.GetGeneratedKeysDelegate; /** * @author Andrea Boriero + * + * @deprecated no longer used, use {@link GetGeneratedKeysDelegate} instead */ +@Deprecated(forRemoval = true) @Remove public class Oracle12cGetGeneratedKeysDelegate extends GetGeneratedKeysDelegate { - private final String[] keyColumns; - public Oracle12cGetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect) { - super( persister, dialect ); - this.keyColumns = getPersister().getRootTableKeyColumnNames(); - if ( keyColumns.length > 1 ) { - throw new HibernateException( "Identity generator cannot be used with multi-column keys" ); - } - - } - - @Override - public PreparedStatement prepareStatement(String insertSql, SharedSessionContractImplementor session) { - final JdbcCoordinator jdbcCoordinator = session.getJdbcCoordinator(); - final MutationStatementPreparer statementPreparer = jdbcCoordinator.getMutationStatementPreparer(); - return statementPreparer.prepareStatement( insertSql, keyColumns ); + super( persister, dialect, false ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cIdentityColumnSupport.java b/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cIdentityColumnSupport.java index c75480c82f..1eafb04f40 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cIdentityColumnSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/identity/Oracle12cIdentityColumnSupport.java @@ -32,7 +32,7 @@ public class Oracle12cIdentityColumnSupport extends IdentityColumnSupportImpl { @Override public GetGeneratedKeysDelegate buildGetGeneratedKeysDelegate( PostInsertIdentityPersister persister, Dialect dialect) { - return new Oracle12cGetGeneratedKeysDelegate( persister, dialect ); + return new GetGeneratedKeysDelegate( persister, dialect, false ); } @Override 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 56fbd40898..8f59f81fa9 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java +++ b/hibernate-core/src/main/java/org/hibernate/id/SelectGenerator.java @@ -11,6 +11,7 @@ import java.util.Properties; import org.hibernate.dialect.Dialect; import org.hibernate.generator.InDatabaseGenerator; import org.hibernate.id.factory.spi.StandardGenerator; +import org.hibernate.id.insert.GetGeneratedKeysDelegate; import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate; import org.hibernate.id.insert.InsertReturningDelegate; import org.hibernate.id.insert.UniqueKeySelectingDelegate; @@ -101,10 +102,10 @@ public class SelectGenerator @Override public InsertGeneratedIdentifierDelegate getGeneratedIdentifierDelegate(PostInsertIdentityPersister persister) { Dialect dialect = persister.getFactory().getJdbcServices().getDialect(); - if ( dialect.supportsInsertReturning() ) { - //TODO: this is not quite right, since TableInsertReturningBuilder and then TableInsertStandard - // ultimately end up calling the SqlAstTranslator to generate the SQL which on H2 delegates - // back to IdentityColumnSupport, and this just might not be an identity column + if ( dialect.supportedInsertReturningGeneratedKeys() ) { + return new GetGeneratedKeysDelegate( persister, dialect, false ); + } + else if ( dialect.supportsInsertReturning() ) { return new InsertReturningDelegate( persister, dialect ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java index 90e41544a3..1e744eabfc 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java @@ -18,6 +18,7 @@ import org.hibernate.engine.jdbc.mutation.JdbcValueBindings; 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.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.id.PostInsertIdentityPersister; @@ -39,11 +40,13 @@ import static org.hibernate.id.IdentifierGeneratorHelper.getGeneratedIdentity; public class GetGeneratedKeysDelegate extends AbstractReturningDelegate { private final PostInsertIdentityPersister persister; private final Dialect dialect; + private final boolean inferredKeys; - public GetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect) { + public GetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect, boolean inferredKeys) { super( persister ); this.persister = persister; this.dialect = dialect; + this.inferredKeys = inferredKeys; } @Override @Deprecated @@ -78,8 +81,10 @@ public class GetGeneratedKeysDelegate extends AbstractReturningDelegate { @Override public PreparedStatement prepareStatement(String insertSql, SharedSessionContractImplementor session) { - return session.getJdbcCoordinator().getMutationStatementPreparer() - .prepareStatement( insertSql, RETURN_GENERATED_KEYS ); + MutationStatementPreparer preparer = session.getJdbcCoordinator().getMutationStatementPreparer(); + return inferredKeys + ? preparer.prepareStatement( insertSql, RETURN_GENERATED_KEYS ) + : preparer.prepareStatement( insertSql, persister.getRootTableKeyColumnNames() ); } @Override