use getGeneratedKeys() in SelectGenerator on Oracle

This commit is contained in:
Gavin 2022-12-19 20:02:13 +01:00 committed by Gavin King
parent ad2d4604fb
commit 0f4cdc3bdb
7 changed files with 28 additions and 31 deletions

View File

@ -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.
*

View File

@ -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().
*
* <p>
* Thus, the additional supported fields are
* {@link TemporalUnit#DAY_OF_YEAR},
* {@link TemporalUnit#DAY_OF_MONTH},

View File

@ -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 );
}
}

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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 {

View File

@ -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