HHH-17424 - Have Dialect manage more of ExtractedDatabaseMetadata
https://hibernate.atlassian.net/browse/HHH-17424
This commit is contained in:
parent
fa5f0f75c2
commit
501b57a978
|
@ -275,8 +275,13 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
final ConfigurationService configurationService = serviceRegistry.getService( ConfigurationService.class );
|
||||
final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class );
|
||||
|
||||
assert jdbcServices != null;
|
||||
assert configurationService != null;
|
||||
|
||||
final Dialect dialect = jdbcServices.getJdbcEnvironment().getDialect();
|
||||
|
||||
final Map<String,Object> configurationSettings = new HashMap<>();
|
||||
configurationSettings.putAll( map( jdbcServices.getJdbcEnvironment().getDialect().getDefaultProperties() ) );
|
||||
configurationSettings.putAll( map( dialect.getDefaultProperties() ) );
|
||||
configurationSettings.putAll( configurationService.getSettings() );
|
||||
|
||||
this.beanManagerReference = NullnessHelper.coalesceSuppliedValues(
|
||||
|
@ -488,7 +493,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
}
|
||||
|
||||
this.jdbcBatchSize = getInt( STATEMENT_BATCH_SIZE, configurationSettings, 1 );
|
||||
if ( !meta.supportsBatchUpdates() ) {
|
||||
if ( disallowBatchUpdates( dialect, meta ) ) {
|
||||
this.jdbcBatchSize = 0;
|
||||
}
|
||||
|
||||
|
@ -585,6 +590,14 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
);
|
||||
}
|
||||
|
||||
private boolean disallowBatchUpdates(Dialect dialect, ExtractedDatabaseMetaData meta) {
|
||||
final Boolean dialectAnswer = dialect.supportsBatchUpdates();
|
||||
if ( dialectAnswer != null ) {
|
||||
return dialectAnswer;
|
||||
}
|
||||
return !meta.supportsBatchUpdates();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private SqmMultiTableMutationStrategy resolveSqmMutationStrategy(
|
||||
String strategyName,
|
||||
|
|
|
@ -4952,6 +4952,30 @@ public abstract class Dialect implements ConversionContext, TypeContributor, Fun
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this Dialect support {@linkplain PreparedStatement#addBatch() batch updates}.
|
||||
*
|
||||
* @return {@code true} indicates it does; {@code false} indicates it does not; {@code null} indicates
|
||||
* it might and that database-metadata should be consulted.
|
||||
*
|
||||
* @see org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData#supportsBatchUpdates
|
||||
*/
|
||||
public Boolean supportsBatchUpdates() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this Dialect support {@linkplain PreparedStatement#addBatch() batch updates}.
|
||||
*
|
||||
* @return {@code true} indicates it does; {@code false} indicates it does not; {@code null} indicates
|
||||
* it might and that database-metadata should be consulted
|
||||
*
|
||||
* @see org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData#supportsRefCursors
|
||||
*/
|
||||
public Boolean supportsRefCursors() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluggable strategy for determining the {@link Size} to use for
|
||||
* columns of a given SQL type.
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||
*/
|
||||
package org.hibernate.engine.jdbc.cursor.internal;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class FallbackRefCursorSupport implements RefCursorSupport {
|
||||
private final JdbcServices jdbcServices;
|
||||
|
||||
public FallbackRefCursorSupport(JdbcServices jdbcServices) {
|
||||
this.jdbcServices = jdbcServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRefCursorParameter(CallableStatement statement, int position) {
|
||||
try {
|
||||
jdbcServices.getDialect().registerResultSetOutParameter( statement, position );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + position + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRefCursorParameter(CallableStatement statement, String name) {
|
||||
try {
|
||||
jdbcServices.getDialect().registerResultSetOutParameter( statement, name );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + name + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement statement, int position) {
|
||||
try {
|
||||
return jdbcServices.getDialect().getResultSet( statement, position );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + position + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement statement, String name) {
|
||||
try {
|
||||
return jdbcServices.getDialect().getResultSet( statement, name );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + name + "]"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.boot.registry.StandardServiceInitiator;
|
||||
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +26,23 @@ public class RefCursorSupportInitiator implements StandardServiceInitiator<RefCu
|
|||
|
||||
@Override
|
||||
public RefCursorSupport initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
|
||||
return new StandardRefCursorSupport();
|
||||
final JdbcServices jdbcServices = registry.getService( JdbcServices.class );
|
||||
assert jdbcServices != null;
|
||||
final boolean supportsRefCursors = useRefCursorSupport( jdbcServices );
|
||||
if ( supportsRefCursors ) {
|
||||
return new StandardRefCursorSupport( jdbcServices );
|
||||
}
|
||||
else {
|
||||
return new FallbackRefCursorSupport( jdbcServices );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean useRefCursorSupport(JdbcServices jdbcServices) {
|
||||
final Boolean dialectAnswer = jdbcServices.getDialect().supportsRefCursors();
|
||||
if ( dialectAnswer != null ) {
|
||||
return dialectAnswer;
|
||||
}
|
||||
return jdbcServices.getJdbcEnvironment().getExtractedDatabaseMetaData().supportsRefCursors();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -15,7 +15,6 @@ import java.sql.Types;
|
|||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.jdbc.cursor.spi.RefCursorSupport;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.service.spi.InjectService;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -27,102 +26,49 @@ import org.jboss.logging.Logger;
|
|||
public class StandardRefCursorSupport implements RefCursorSupport {
|
||||
private static final Logger log = Logger.getLogger( StandardRefCursorSupport.class );
|
||||
|
||||
private JdbcServices jdbcServices;
|
||||
private final JdbcServices jdbcServices;
|
||||
|
||||
/**
|
||||
* Hook for service registry to be able to inject JdbcServices
|
||||
*
|
||||
* @param jdbcServices The JdbcServices service
|
||||
*/
|
||||
@InjectService
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
public void injectJdbcServices(JdbcServices jdbcServices) {
|
||||
public StandardRefCursorSupport(JdbcServices jdbcServices) {
|
||||
this.jdbcServices = jdbcServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRefCursorParameter(CallableStatement statement, int position) {
|
||||
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
|
||||
try {
|
||||
statement.registerOutParameter( position, refCursorTypeCode() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + position + "]" );
|
||||
}
|
||||
try {
|
||||
statement.registerOutParameter( position, refCursorTypeCode() );
|
||||
}
|
||||
else {
|
||||
try {
|
||||
jdbcServices.getDialect().registerResultSetOutParameter( statement, position );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + position + "]" );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + position + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRefCursorParameter(CallableStatement statement, String name) {
|
||||
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
|
||||
try {
|
||||
statement.registerOutParameter( name, refCursorTypeCode() );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + name + "]" );
|
||||
}
|
||||
try {
|
||||
statement.registerOutParameter( name, refCursorTypeCode() );
|
||||
}
|
||||
else {
|
||||
try {
|
||||
jdbcServices.getDialect().registerResultSetOutParameter( statement, name );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error asking dialect to register ref cursor parameter [" + name + "]" );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert( e, "Error registering REF_CURSOR parameter [" + name + "]" );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement statement, int position) {
|
||||
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
|
||||
try {
|
||||
return statement.getObject( position, ResultSet.class );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + position + "]", e );
|
||||
}
|
||||
try {
|
||||
return statement.getObject( position, ResultSet.class );
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return jdbcServices.getDialect().getResultSet( statement, position );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + position + "]"
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + position + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet getResultSet(CallableStatement statement, String name) {
|
||||
if ( jdbcServices.getExtractedMetaDataSupport().supportsRefCursors() ) {
|
||||
try {
|
||||
return statement.getObject( name, ResultSet.class );
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + name + "]", e );
|
||||
}
|
||||
try {
|
||||
return statement.getObject( name, ResultSet.class );
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return jdbcServices.getDialect().getResultSet( statement, name );
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw jdbcServices.getSqlExceptionHelper().convert(
|
||||
e,
|
||||
"Error asking dialect to extract ResultSet from CallableStatement parameter [" + name + "]"
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new HibernateException( "Unexpected error extracting REF_CURSOR parameter [" + name + "]", e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.engine.jdbc.env.spi;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
|
||||
|
||||
/**
|
||||
|
@ -30,6 +31,8 @@ public interface ExtractedDatabaseMetaData {
|
|||
* Retrieve the name of the catalog in effect when we connected to the database.
|
||||
*
|
||||
* @return The catalog name
|
||||
*
|
||||
* @see AvailableSettings#DEFAULT_SCHEMA
|
||||
*/
|
||||
String getConnectionCatalogName();
|
||||
|
||||
|
@ -45,14 +48,19 @@ public interface ExtractedDatabaseMetaData {
|
|||
*
|
||||
* @return {@code true} indicates the driver reported true; {@code false} indicates the driver reported false
|
||||
* or that the driver could not be asked.
|
||||
*
|
||||
* @see AvailableSettings#CALLABLE_NAMED_PARAMS_ENABLED
|
||||
*/
|
||||
boolean supportsNamedParameters();
|
||||
|
||||
/**
|
||||
* Does the driver report supporting REF_CURSORs?
|
||||
* Does the driver report supporting {@link java.sql.Types#REF_CURSOR}?
|
||||
*
|
||||
* @return {@code true} indicates the driver reported true; {@code false} indicates the driver reported false
|
||||
* or that the driver could not be asked.
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#supportsRefCursors()
|
||||
* @see org.hibernate.dialect.Dialect#supportsRefCursors
|
||||
*/
|
||||
boolean supportsRefCursors();
|
||||
|
||||
|
@ -62,15 +70,17 @@ public interface ExtractedDatabaseMetaData {
|
|||
* @return True if the driver reported to support {@link java.sql.ResultSet#TYPE_SCROLL_INSENSITIVE}.
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#supportsResultSetType
|
||||
* @see AvailableSettings#USE_SCROLLABLE_RESULTSET
|
||||
*/
|
||||
boolean supportsScrollableResults();
|
||||
|
||||
/**
|
||||
* Did the driver report to supporting retrieval of generated keys?
|
||||
*
|
||||
* @return True if the if the driver reported to support calls to {@link java.sql.Statement#getGeneratedKeys}
|
||||
* @return True if the driver reported to support calls to {@link java.sql.Statement#getGeneratedKeys}
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#supportsGetGeneratedKeys
|
||||
* @see AvailableSettings#USE_GET_GENERATED_KEYS
|
||||
*/
|
||||
boolean supportsGetGeneratedKeys();
|
||||
|
||||
|
@ -80,6 +90,7 @@ public interface ExtractedDatabaseMetaData {
|
|||
* @return True if the driver supports batched updates
|
||||
*
|
||||
* @see java.sql.DatabaseMetaData#supportsBatchUpdates
|
||||
* @see org.hibernate.dialect.Dialect#supportsBatchUpdates
|
||||
*/
|
||||
boolean supportsBatchUpdates();
|
||||
|
||||
|
|
Loading…
Reference in New Issue