From 10def48f48ca56383626740dc0ce1ba1eff0a82e Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 28 Jul 2016 15:40:58 -0500 Subject: [PATCH] HHH-10896 - Exception thrown when dropping schema with a managed connection --- .../AbstractMultiTenancyTest.java | 22 ++--- .../DdlTransactionIsolatorNonJtaImpl.java | 66 +++++++++++++ ...ocalTransactionCoordinatorBuilderImpl.java | 7 ++ .../DdlTransactionIsolatorJtaImpl.java | 88 +++++++++++++++++ .../JtaTransactionCoordinatorBuilderImpl.java | 7 ++ .../spi/DdlTransactionIsolator.java | 36 +++++++ .../spi/TransactionCoordinatorBuilder.java | 7 ++ .../spi/TransactionCoordinatorOwner.java | 2 +- ...sactionIsolatorProvidedConnectionImpl.java | 47 +++++++++ .../DdlTransactionIsolatorSharedImpl.java | 46 +++++++++ .../tool/schema/internal/Helper.java | 6 +- .../HibernateSchemaManagementTool.java | 55 +++++++---- .../schema/internal/SchemaCreatorImpl.java | 12 ++- .../schema/internal/SchemaDropperImpl.java | 78 ++++++++++----- .../schema/internal/SchemaMigratorImpl.java | 19 ++-- .../schema/internal/SchemaValidatorImpl.java | 7 +- .../AbstractJdbcConnectionContextImpl.java | 96 ------------------- .../exec/GenerationTargetToDatabase.java | 50 ++++------ .../exec/ImprovedDatabaseInformationImpl.java | 5 +- .../exec/ImprovedExtractionContextImpl.java | 11 ++- .../internal/exec/JdbcConnectionContext.java | 22 ----- .../JdbcConnectionContextNonSharedImpl.java | 29 ------ .../exec/JdbcConnectionContextSharedImpl.java | 34 ------- .../schema/internal/exec/JdbcContext.java | 6 ++ .../connections/SuppliedConnectionTest.java | 17 +--- .../schema/SchemaBasedMultiTenancyTest.java | 18 ++-- .../test/quote/TableGeneratorQuotingTest.java | 10 +- .../schema/DropSchemaDuringJtaTxnTest.java | 71 ++++++++++++++ .../tool/schema/SchemaValidatorImplTest.java | 17 ++-- .../DdlTransactionIsolatorTestingImpl.java | 74 ++++++++++++++ 30 files changed, 627 insertions(+), 338 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/DdlTransactionIsolator.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorProvidedConnectionImpl.java create mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorSharedImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/AbstractJdbcConnectionContextImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContext.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextNonSharedImpl.java delete mode 100644 hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextSharedImpl.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/tool/schema/DropSchemaDuringJtaTxnTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/test/util/DdlTransactionIsolatorTestingImpl.java diff --git a/documentation/src/test/java/org/hibernate/userguide/multitenancy/AbstractMultiTenancyTest.java b/documentation/src/test/java/org/hibernate/userguide/multitenancy/AbstractMultiTenancyTest.java index d4bd94e194..b0f60e1335 100644 --- a/documentation/src/test/java/org/hibernate/userguide/multitenancy/AbstractMultiTenancyTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/multitenancy/AbstractMultiTenancyTest.java @@ -28,18 +28,16 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Environment; import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.Stoppable; import org.hibernate.tool.schema.internal.HibernateSchemaManagementTool; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; import org.hibernate.tool.schema.internal.SchemaDropperImpl; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.testing.AfterClassOnce; -import org.hibernate.testing.boot.JdbcConnectionAccessImpl; import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.test.util.DdlTransactionIsolatorTestingImpl; import org.junit.Test; /** @@ -150,18 +148,16 @@ public abstract class AbstractMultiTenancyTest extends BaseUnitTestCase { tool.injectServices( serviceRegistry ); final GenerationTargetToDatabase frontEndSchemaGenerator = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( connectionProviderMap.get( FRONT_END_TENANT ) ), - new SqlStatementLogger( false, true ), - true - ) + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + connectionProviderMap.get( FRONT_END_TENANT ) + ) ); final GenerationTargetToDatabase backEndSchemaGenerator = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( connectionProviderMap.get( BACK_END_TENANT ) ), - new SqlStatementLogger( false, true ), - true - ) + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + connectionProviderMap.get( BACK_END_TENANT ) + ) ); new SchemaDropperImpl( serviceRegistry ).doDrop( diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java new file mode 100644 index 0000000000..bd21b9fc50 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/DdlTransactionIsolatorNonJtaImpl.java @@ -0,0 +1,66 @@ +/* + * 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 . + */ +package org.hibernate.resource.transaction.backend.jdbc.internal; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; +import org.hibernate.tool.schema.internal.exec.JdbcContext; + +/** + * DdlExecutor for use in non-JTA environments (JDBC transaction) + * + * @author Steve Ebersole + */ +public class DdlTransactionIsolatorNonJtaImpl implements DdlTransactionIsolator { + private final JdbcContext jdbcContext; + + private Connection jdbcConnection; + + public DdlTransactionIsolatorNonJtaImpl(JdbcContext jdbcContext) { + this.jdbcContext = jdbcContext; + } + + @Override + public void prepare() { + } + + @Override + public JdbcContext getJdbcContext() { + return jdbcContext; + } + + @Override + public Connection getIsolatedConnection() { + if ( jdbcConnection == null ) { + try { + this.jdbcConnection = jdbcContext.getJdbcConnectionAccess().obtainConnection(); + } + catch (SQLException e) { + throw jdbcContext.getSqlExceptionHelper().convert( + e, + "Unable to open JDBC Connection for DDL execution" + ); + } + } + + return jdbcConnection; + } + + @Override + public void release() { + if ( jdbcConnection != null ) { + try { + jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection ); + } + catch (SQLException e) { + throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable to release JDBC Connection used for DDL execution" ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorBuilderImpl.java index 1b98876ebf..8048ae3acb 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jdbc/internal/JdbcResourceLocalTransactionCoordinatorBuilderImpl.java @@ -9,9 +9,11 @@ package org.hibernate.resource.transaction.backend.jdbc.internal; import org.hibernate.HibernateException; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; import org.hibernate.resource.transaction.backend.jdbc.spi.JdbcResourceTransactionAccess; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner; +import org.hibernate.tool.schema.internal.exec.JdbcContext; /** * Concrete builder for resource-local TransactionCoordinator instances. @@ -46,4 +48,9 @@ public class JdbcResourceLocalTransactionCoordinatorBuilderImpl implements Trans public PhysicalConnectionHandlingMode getDefaultConnectionHandlingMode() { return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_TRANSACTION; } + + @Override + public DdlTransactionIsolator buildDdlTransactionIsolator(JdbcContext jdbcContext) { + return new DdlTransactionIsolatorNonJtaImpl( jdbcContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java new file mode 100644 index 0000000000..6651562630 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/DdlTransactionIsolatorJtaImpl.java @@ -0,0 +1,88 @@ +/* + * 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 . + */ +package org.hibernate.resource.transaction.backend.jta.internal; + +import java.sql.Connection; +import java.sql.SQLException; +import javax.transaction.SystemException; +import javax.transaction.Transaction; + +import org.hibernate.HibernateException; +import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; +import org.hibernate.tool.schema.internal.exec.JdbcContext; + +/** + * DdlExecutor for use in JTA environments + * + * @author Steve Ebersole + */ +public class DdlTransactionIsolatorJtaImpl implements DdlTransactionIsolator { + private final JdbcContext jdbcContext; + + private Transaction suspendedTransaction; + private Connection jdbcConnection; + + public DdlTransactionIsolatorJtaImpl(JdbcContext jdbcContext) { + this.jdbcContext = jdbcContext; + } + + @Override + public JdbcContext getJdbcContext() { + return jdbcContext; + } + + @Override + public void prepare() { + try { + this.suspendedTransaction = jdbcContext.getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().suspend(); + } + catch (SystemException e) { + throw new HibernateException( "Unable to suspend current JTA transaction in preparation for DDL execution" ); + } + + try { + this.jdbcConnection = jdbcContext.getJdbcConnectionAccess().obtainConnection(); + } + catch (SQLException e) { + throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable to open JDBC Connection for DDL execution" ); + } + + try { + jdbcConnection.setAutoCommit( true ); + } + catch (SQLException e) { + throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable set JDBC Connection for DDL execution to autocommit" ); + } + } + + @Override + public Connection getIsolatedConnection() { + return jdbcConnection; + } + + @Override + public void release() { + if ( jdbcConnection != null ) { + try { + jdbcContext.getJdbcConnectionAccess().releaseConnection( jdbcConnection ); + } + catch (SQLException e) { + throw jdbcContext.getSqlExceptionHelper().convert( e, "Unable to release JDBC Connection used for DDL execution" ); + } + } + + if ( suspendedTransaction != null ) { + try { + jdbcContext.getServiceRegistry().getService( JtaPlatform.class ).retrieveTransactionManager().resume( suspendedTransaction ); + } + catch (Exception e) { + throw new HibernateException( "Unable to resume JTA transaction after DDL execution" ); + } + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorBuilderImpl.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorBuilderImpl.java index c9f118e6b8..412daf5b97 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorBuilderImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/backend/jta/internal/JtaTransactionCoordinatorBuilderImpl.java @@ -7,9 +7,11 @@ package org.hibernate.resource.transaction.backend.jta.internal; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.resource.transaction.spi.TransactionCoordinator; import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; import org.hibernate.resource.transaction.spi.TransactionCoordinatorOwner; +import org.hibernate.tool.schema.internal.exec.JdbcContext; /** * Concrete builder for JTA-based TransactionCoordinator instances. @@ -38,4 +40,9 @@ public class JtaTransactionCoordinatorBuilderImpl implements TransactionCoordina // todo : I want to change this to PhysicalConnectionHandlingMode#IMMEDIATE_ACQUISITION_AND_HOLD return PhysicalConnectionHandlingMode.DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT; } + + @Override + public DdlTransactionIsolator buildDdlTransactionIsolator(JdbcContext jdbcContext) { + return new DdlTransactionIsolatorJtaImpl( jdbcContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/DdlTransactionIsolator.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/DdlTransactionIsolator.java new file mode 100644 index 0000000000..2f0d95646c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/DdlTransactionIsolator.java @@ -0,0 +1,36 @@ +/* + * 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 . + */ +package org.hibernate.resource.transaction.spi; + +import java.sql.Connection; + +import org.hibernate.tool.schema.internal.exec.JdbcContext; + +/** + * Provides access to a Connection that is isolated from + * any "current transaction" with the designed purpose of + * performing DDL commands + * + * @author Steve Ebersole + */ +public interface DdlTransactionIsolator { + JdbcContext getJdbcContext(); + + void prepare(); + + /** + * Returns a Connection that is usable within the bounds of the + * {@link #prepare} and {@link #release} calls. Further, this + * Connection will be isolated (transactionally) from any + * transaction in effect prior to the call to {@link #prepare}. + * + * @return + */ + Connection getIsolatedConnection(); + + void release(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorBuilder.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorBuilder.java index b2a062d618..ab638eafbe 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorBuilder.java @@ -9,7 +9,10 @@ package org.hibernate.resource.transaction.spi; import org.hibernate.ConnectionAcquisitionMode; import org.hibernate.ConnectionReleaseMode; import org.hibernate.resource.jdbc.spi.PhysicalConnectionHandlingMode; +import org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl; +import org.hibernate.resource.transaction.backend.jta.internal.DdlTransactionIsolatorJtaImpl; import org.hibernate.service.Service; +import org.hibernate.tool.schema.internal.exec.JdbcContext; /** * Builder for TransactionCoordinator instances @@ -52,4 +55,8 @@ public interface TransactionCoordinatorBuilder extends Service { default ConnectionReleaseMode getDefaultConnectionReleaseMode() { return getDefaultConnectionHandlingMode().getReleaseMode(); } + + default DdlTransactionIsolator buildDdlTransactionIsolator(JdbcContext jdbcContext) { + return isJta() ? new DdlTransactionIsolatorJtaImpl( jdbcContext ) : new DdlTransactionIsolatorNonJtaImpl( jdbcContext ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorOwner.java b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorOwner.java index 54325db333..d2840e3718 100644 --- a/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorOwner.java +++ b/hibernate-core/src/main/java/org/hibernate/resource/transaction/spi/TransactionCoordinatorOwner.java @@ -14,7 +14,7 @@ import org.hibernate.resource.jdbc.spi.JdbcSessionOwner; * First to allow the coordinator to determine if its owner is still active (open, etc). * *
  • - * Second is to allow the coordinator to dispatch beforeQuery and afterQuery completion events to the owner + * Second is to allow the coordinator to dispatch before and after completion events to the owner *
  • * * diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorProvidedConnectionImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorProvidedConnectionImpl.java new file mode 100644 index 0000000000..e6ad31ddc2 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorProvidedConnectionImpl.java @@ -0,0 +1,47 @@ +package org.hibernate.tool.schema.internal; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; +import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessProvidedConnectionImpl; +import org.hibernate.tool.schema.internal.exec.JdbcContext; +import org.hibernate.tool.schema.spi.SchemaManagementException; + +/** + * Specialized DdlTransactionIsolator for cases where we have a user provided Connection + * + * @author Steve Ebersole + */ +class DdlTransactionIsolatorProvidedConnectionImpl implements DdlTransactionIsolator { + private final JdbcContext jdbcContext; + + public DdlTransactionIsolatorProvidedConnectionImpl(JdbcContext jdbcContext) { + assert jdbcContext.getJdbcConnectionAccess() instanceof JdbcConnectionAccessProvidedConnectionImpl; + this.jdbcContext = jdbcContext; + } + + @Override + public JdbcContext getJdbcContext() { + return jdbcContext; + } + + @Override + public Connection getIsolatedConnection() { + try { + return jdbcContext.getJdbcConnectionAccess().obtainConnection(); + } + catch (SQLException e) { + // should never happen + throw new SchemaManagementException( "Error accessing user-provided Connection via JdbcConnectionAccessProvidedConnectionImpl", e ); + } + } + + @Override + public void prepare() { + } + + @Override + public void release() { + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorSharedImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorSharedImpl.java new file mode 100644 index 0000000000..720ae190a9 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/DdlTransactionIsolatorSharedImpl.java @@ -0,0 +1,46 @@ +/* + * 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 . + */ +package org.hibernate.tool.schema.internal; + +import java.sql.Connection; + +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; +import org.hibernate.tool.schema.internal.exec.JdbcContext; + +/** + * A DdlTransactionIsolator implementations for use in cases where the + * isolated Connection is shared. + * + * @author Steve Ebersole + */ +public class DdlTransactionIsolatorSharedImpl implements DdlTransactionIsolator { + private final DdlTransactionIsolator wrappedIsolator; + + public DdlTransactionIsolatorSharedImpl(DdlTransactionIsolator ddlTransactionIsolator) { + this.wrappedIsolator = ddlTransactionIsolator; + } + + @Override + public JdbcContext getJdbcContext() { + return wrappedIsolator.getJdbcContext(); + } + + @Override + public void prepare() { + // skip delegating the call to prepare + } + + @Override + public Connection getIsolatedConnection() { + return wrappedIsolator.getIsolatedConnection(); + } + + @Override + public void release() { + // skip delegating the call to prepare + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/Helper.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/Helper.java index dd43c7d90b..3fc4159046 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/Helper.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/Helper.java @@ -18,10 +18,10 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.schema.extract.spi.DatabaseInformation; import org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContext; import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromFile; import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromReader; import org.hibernate.tool.schema.internal.exec.ScriptSourceInputFromUrl; @@ -119,14 +119,14 @@ public class Helper { public static DatabaseInformation buildDatabaseInformation( ServiceRegistry serviceRegistry, - JdbcConnectionContext connectionContext, + DdlTransactionIsolator ddlTransactionIsolator, Namespace.Name defaultNamespace) { final JdbcEnvironment jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class ); try { return new ImprovedDatabaseInformationImpl( serviceRegistry, jdbcEnvironment, - connectionContext, + ddlTransactionIsolator, defaultNamespace ); } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java index c0d23a6f94..d28cb703c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/HibernateSchemaManagementTool.java @@ -15,11 +15,13 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; import org.hibernate.engine.jdbc.dialect.spi.DialectResolver; -import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.config.ConfigurationHelper; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; +import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryImplementor; @@ -29,8 +31,6 @@ import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; import org.hibernate.tool.schema.internal.exec.GenerationTargetToScript; import org.hibernate.tool.schema.internal.exec.GenerationTargetToStdout; import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessProvidedConnectionImpl; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContext; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.tool.schema.internal.exec.JdbcContext; import org.hibernate.tool.schema.spi.SchemaCreator; import org.hibernate.tool.schema.spi.SchemaDropper; @@ -117,15 +117,7 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv } if ( targetDescriptor.getTargetTypes().contains( TargetType.DATABASE ) ) { - targets[index] = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - jdbcContext.getJdbcConnectionAccess(), - jdbcContext.getSqlStatementLogger(), - needsAutoCommit - ) - , serviceRegistry.getService( JdbcEnvironment.class ).getSqlExceptionHelper() - ); - + targets[index] = new GenerationTargetToDatabase( getDdlTransactionIsolator( jdbcContext ) ); } return targets; @@ -133,7 +125,7 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv GenerationTarget[] buildGenerationTargets( TargetDescriptor targetDescriptor, - JdbcConnectionContext connectionContext, + DdlTransactionIsolator ddlTransactionIsolator, Map options) { final String scriptDelimiter = ConfigurationHelper.getString( HBM2DDL_DELIMITER, options ); @@ -155,13 +147,19 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv } if ( targetDescriptor.getTargetTypes().contains( TargetType.DATABASE ) ) { - targets[index] = new GenerationTargetToDatabase( connectionContext - , serviceRegistry.getService( JdbcEnvironment.class ).getSqlExceptionHelper() ); + targets[index] = new GenerationTargetToDatabase( ddlTransactionIsolator ); } return targets; } + public DdlTransactionIsolator getDdlTransactionIsolator(JdbcContext jdbcContext) { + if ( jdbcContext.getJdbcConnectionAccess() instanceof JdbcConnectionAccessProvidedConnectionImpl ) { + return new DdlTransactionIsolatorProvidedConnectionImpl( jdbcContext ); + } + return serviceRegistry.getService( TransactionCoordinatorBuilder.class ).buildDdlTransactionIsolator( jdbcContext ); + } + public JdbcContext resolveJdbcContext(Map configurationValues) { final JdbcContextBuilder jdbcContextBuilder = new JdbcContextBuilder( serviceRegistry ); @@ -236,19 +234,25 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv } private static class JdbcContextBuilder { + private final ServiceRegistry serviceRegistry; private final SqlStatementLogger sqlStatementLogger; + private final SqlExceptionHelper sqlExceptionHelper; + private JdbcConnectionAccess jdbcConnectionAccess; private Dialect dialect; public JdbcContextBuilder(ServiceRegistry serviceRegistry) { + this.serviceRegistry = serviceRegistry; final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); this.sqlStatementLogger = jdbcServices.getSqlStatementLogger(); + this.sqlExceptionHelper = jdbcServices.getSqlExceptionHelper(); + this.dialect = jdbcServices.getJdbcEnvironment().getDialect(); this.jdbcConnectionAccess = jdbcServices.getBootstrapJdbcConnectionAccess(); } public JdbcContext buildJdbcContext() { - return new JdbcContextImpl( jdbcConnectionAccess, dialect, sqlStatementLogger ); + return new JdbcContextImpl( jdbcConnectionAccess, dialect, sqlStatementLogger, sqlExceptionHelper, serviceRegistry ); } } @@ -256,14 +260,20 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv private final JdbcConnectionAccess jdbcConnectionAccess; private final Dialect dialect; private final SqlStatementLogger sqlStatementLogger; + private final SqlExceptionHelper sqlExceptionHelper; + private final ServiceRegistry serviceRegistry; private JdbcContextImpl( JdbcConnectionAccess jdbcConnectionAccess, Dialect dialect, - SqlStatementLogger sqlStatementLogger) { + SqlStatementLogger sqlStatementLogger, + SqlExceptionHelper sqlExceptionHelper, + ServiceRegistry serviceRegistry) { this.jdbcConnectionAccess = jdbcConnectionAccess; this.dialect = dialect; this.sqlStatementLogger = sqlStatementLogger; + this.sqlExceptionHelper = sqlExceptionHelper; + this.serviceRegistry = serviceRegistry; } @Override @@ -280,5 +290,16 @@ public class HibernateSchemaManagementTool implements SchemaManagementTool, Serv public SqlStatementLogger getSqlStatementLogger() { return sqlStatementLogger; } + + @Override + public SqlExceptionHelper getSqlExceptionHelper() { + return sqlExceptionHelper; + } + + @Override + public ServiceRegistry getServiceRegistry() { + return serviceRegistry; + } } + } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java index 89348ea91c..79e0a3306b 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaCreatorImpl.java @@ -287,11 +287,15 @@ public class SchemaCreatorImpl implements SchemaCreator { } checkExportIdentifier( sequence, exportIdentifiers ); applySqlStrings( - dialect.getCreateSequenceStrings( - jdbcEnvironment.getQualifiedObjectNameFormatter().format( sequence.getName(), dialect ), - sequence.getInitialValue(), - sequence.getIncrementSize() + dialect.getSequenceExporter().getSqlCreateStrings( + sequence, + metadata ), +// dialect.getCreateSequenceStrings( +// jdbcEnvironment.getQualifiedObjectNameFormatter().format( sequence.getName(), dialect ), +// sequence.getInitialValue(), +// sequence.getIncrementSize() +// ), formatter, options, targets diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java index 9059799383..4ad198d4e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaDropperImpl.java @@ -25,24 +25,25 @@ import org.hibernate.boot.model.relational.Sequence; import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; -import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.internal.FormatStyle; import org.hibernate.engine.jdbc.internal.Formatter; import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Table; +import org.hibernate.resource.transaction.spi.TransactionCoordinatorBuilder; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.tool.hbm2ddl.ImportSqlCommandExtractor; import org.hibernate.tool.schema.SourceType; import org.hibernate.tool.schema.internal.exec.GenerationTarget; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessConnectionProviderImpl; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.tool.schema.internal.exec.JdbcContext; import org.hibernate.tool.schema.spi.CommandAcceptanceException; import org.hibernate.tool.schema.spi.DelayedDropAction; @@ -447,14 +448,9 @@ public class SchemaDropperImpl implements SchemaDropper { if ( targets == null || targets.length == 0 ) { final JdbcContext jdbcContext = tool.resolveJdbcContext( settings ); targets = new GenerationTarget[] { - new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - jdbcContext.getJdbcConnectionAccess(), - jdbcContext.getSqlStatementLogger(), - true - ) - , serviceRegistry.getService( JdbcEnvironment.class ).getSqlExceptionHelper() - ) + new GenerationTargetToDatabase( + serviceRegistry.getService( TransactionCoordinatorBuilder.class ).buildDdlTransactionIsolator( jdbcContext ) + ) }; } @@ -522,22 +518,11 @@ public class SchemaDropperImpl implements SchemaDropper { public void perform(ServiceRegistry serviceRegistry) { log.startingDelayedSchemaDrop(); - final ConnectionProvider connectionProvider = serviceRegistry.getService( ConnectionProvider.class ); - if ( connectionProvider == null ) { - // todo : log or error? - throw new SchemaManagementException( - "Could not build JDBC Connection context to drop schema on SessionFactory close" - ); - } - + final JdbcContext jdbcContext = new JdbcContextDelayedDropImpl( serviceRegistry ); final GenerationTargetToDatabase target = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessConnectionProviderImpl( connectionProvider ), - serviceRegistry.getService( JdbcServices.class ).getSqlStatementLogger(), - true - ) - , serviceRegistry.getService( JdbcEnvironment.class ).getSqlExceptionHelper() + serviceRegistry.getService( TransactionCoordinatorBuilder.class ).buildDdlTransactionIsolator( jdbcContext ) ); + target.prepare(); try { for ( String command : commands ) { @@ -556,5 +541,48 @@ public class SchemaDropperImpl implements SchemaDropper { target.release(); } } + + private class JdbcContextDelayedDropImpl implements JdbcContext { + private final ServiceRegistry serviceRegistry; + private final JdbcServices jdbcServices; + private final JdbcConnectionAccess jdbcConnectionAccess; + + public JdbcContextDelayedDropImpl(ServiceRegistry serviceRegistry) { + this.serviceRegistry = serviceRegistry; + this.jdbcServices = serviceRegistry.getService( JdbcServices.class ); + this.jdbcConnectionAccess = jdbcServices.getBootstrapJdbcConnectionAccess(); + if ( jdbcConnectionAccess == null ) { + // todo : log or error? + throw new SchemaManagementException( + "Could not build JDBC Connection context to drop schema on SessionFactory close" + ); + } + } + + @Override + public JdbcConnectionAccess getJdbcConnectionAccess() { + return jdbcConnectionAccess; + } + + @Override + public Dialect getDialect() { + return jdbcServices.getJdbcEnvironment().getDialect(); + } + + @Override + public SqlStatementLogger getSqlStatementLogger() { + return jdbcServices.getSqlStatementLogger(); + } + + @Override + public SqlExceptionHelper getSqlExceptionHelper() { + return jdbcServices.getSqlExceptionHelper(); + } + + @Override + public ServiceRegistry getServiceRegistry() { + return serviceRegistry; + } + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java index 3abdb205ea..4eca349ceb 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaMigratorImpl.java @@ -29,15 +29,14 @@ import org.hibernate.mapping.ForeignKey; import org.hibernate.mapping.Index; import org.hibernate.mapping.Table; import org.hibernate.mapping.UniqueKey; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.tool.hbm2ddl.UniqueConstraintSchemaUpdateStrategy; -import org.hibernate.tool.schema.TargetType; import org.hibernate.tool.schema.extract.spi.DatabaseInformation; import org.hibernate.tool.schema.extract.spi.ForeignKeyInformation; import org.hibernate.tool.schema.extract.spi.IndexInformation; import org.hibernate.tool.schema.extract.spi.SequenceInformation; import org.hibernate.tool.schema.extract.spi.TableInformation; import org.hibernate.tool.schema.internal.exec.GenerationTarget; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextSharedImpl; import org.hibernate.tool.schema.internal.exec.JdbcContext; import org.hibernate.tool.schema.spi.CommandAcceptanceException; import org.hibernate.tool.schema.spi.ExecutionOptions; @@ -87,22 +86,22 @@ public class SchemaMigratorImpl implements SchemaMigrator { final JdbcContext jdbcContext = tool.resolveJdbcContext( options.getConfigurationValues() ); - final JdbcConnectionContextSharedImpl connectionContext = new JdbcConnectionContextSharedImpl( - jdbcContext.getJdbcConnectionAccess(), - jdbcContext.getSqlStatementLogger(), - targetDescriptor.getTargetTypes().contains( TargetType.DATABASE ) - ); + final DdlTransactionIsolator ddlTransactionIsolator = tool.getDdlTransactionIsolator( jdbcContext ); try { + ddlTransactionIsolator.prepare(); + + final DdlTransactionIsolator sharedDdlTransactionIsolator = new DdlTransactionIsolatorSharedImpl( ddlTransactionIsolator ); + final DatabaseInformation databaseInformation = Helper.buildDatabaseInformation( tool.getServiceRegistry(), - connectionContext, + sharedDdlTransactionIsolator, metadata.getDatabase().getDefaultNamespace().getName() ); final GenerationTarget[] targets = tool.buildGenerationTargets( targetDescriptor, - connectionContext, + sharedDdlTransactionIsolator, options.getConfigurationValues() ); @@ -119,7 +118,7 @@ public class SchemaMigratorImpl implements SchemaMigrator { } } finally { - connectionContext.reallyRelease(); + ddlTransactionIsolator.release(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java index 008816207c..0d7db1e6ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/SchemaValidatorImpl.java @@ -21,7 +21,6 @@ import org.hibernate.tool.schema.extract.spi.ColumnInformation; import org.hibernate.tool.schema.extract.spi.DatabaseInformation; import org.hibernate.tool.schema.extract.spi.SequenceInformation; import org.hibernate.tool.schema.extract.spi.TableInformation; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.tool.schema.internal.exec.JdbcContext; import org.hibernate.tool.schema.spi.ExecutionOptions; import org.hibernate.tool.schema.spi.SchemaFilter; @@ -55,11 +54,7 @@ public class SchemaValidatorImpl implements SchemaValidator { final DatabaseInformation databaseInformation = Helper.buildDatabaseInformation( tool.getServiceRegistry(), - new JdbcConnectionContextNonSharedImpl( - jdbcContext.getJdbcConnectionAccess(), - jdbcContext.getSqlStatementLogger(), - false - ), + tool.getDdlTransactionIsolator( jdbcContext ), metadata.getDatabase().getDefaultNamespace().getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/AbstractJdbcConnectionContextImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/AbstractJdbcConnectionContextImpl.java deleted file mode 100644 index 51e6a28a47..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/AbstractJdbcConnectionContextImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.tool.schema.internal.exec; - -import java.sql.Connection; -import java.sql.SQLException; - -import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; -import org.hibernate.engine.jdbc.internal.FormatStyle; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; -import org.hibernate.tool.schema.spi.SchemaManagementException; - -/** - * Basic support for JdbcConnectionContext implementations - * - * @author Steve Ebersole - */ -public abstract class AbstractJdbcConnectionContextImpl implements JdbcConnectionContext { - private final JdbcConnectionAccess jdbcConnectionAccess; - private final SqlStatementLogger sqlStatementLogger; - private final boolean needsAutoCommit; - - private Connection jdbcConnection; - private boolean wasInitiallyAutoCommit; - - public AbstractJdbcConnectionContextImpl( - JdbcConnectionAccess jdbcConnectionAccess, - SqlStatementLogger sqlStatementLogger, - boolean needsAutoCommit) { - this.jdbcConnectionAccess = jdbcConnectionAccess; - this.sqlStatementLogger = sqlStatementLogger; - this.needsAutoCommit = needsAutoCommit; - } - - @Override - public Connection getConnection() { - if ( jdbcConnection == null ) { - try { - this.jdbcConnection = jdbcConnectionAccess.obtainConnection(); - } - catch (SQLException e) { - throw new SchemaManagementException( "Unable to obtain JDBC Connection", e ); - } - try { - if ( needsAutoCommit ) { - wasInitiallyAutoCommit = jdbcConnection.getAutoCommit(); - jdbcConnection.setAutoCommit( true ); - } - } - catch (SQLException e) { - throw new SchemaManagementException( "Unable to manage auto-commit", e ); - } - } - return jdbcConnection; - } - - @Override - public void logSqlStatement(String sqlStatement) { - // we explicitly use no formatting here because the statements we get - // will already be formatted if need be - sqlStatementLogger.logStatement( sqlStatement, FormatStyle.NONE.getFormatter() ); - } - - protected void reallyRelease() { - if ( jdbcConnection != null ) { - try { - if ( ! jdbcConnection.getAutoCommit() ) { - jdbcConnection.commit(); - } - else { - // we possibly enabled auto-commit on the Connection, reset if needed - if ( needsAutoCommit && !wasInitiallyAutoCommit ) { - jdbcConnection.setAutoCommit( false ); - } - } - } - catch (SQLException e) { - throw new SchemaManagementException( - "Unable to reset auto-commit afterQuery schema management; may or may not be a problem", - e - ); - } - - try { - jdbcConnectionAccess.releaseConnection( jdbcConnection ); - } - catch (SQLException e) { - throw new SchemaManagementException( "Unable to release JDBC Connection", e ); - } - } - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/GenerationTargetToDatabase.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/GenerationTargetToDatabase.java index 6dc25ab196..bbe363f6e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/GenerationTargetToDatabase.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/GenerationTargetToDatabase.java @@ -10,11 +10,11 @@ import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; -import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.jdbc.internal.DDLFormatterImpl; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.tool.schema.spi.CommandAcceptanceException; -import org.hibernate.tool.schema.spi.SchemaManagementException; /** * GenerationTarget implementation for handling generation directly to the database @@ -24,35 +24,34 @@ import org.hibernate.tool.schema.spi.SchemaManagementException; public class GenerationTargetToDatabase implements GenerationTarget { private static final CoreMessageLogger log = CoreLogging.messageLogger( GenerationTargetToDatabase.class ); - private final SqlExceptionHelper sqlExceptionHelper; - private final JdbcConnectionContext jdbcConnectionContext; + private final DdlTransactionIsolator ddlTransactionIsolator; private Statement jdbcStatement; - public GenerationTargetToDatabase(JdbcConnectionContext jdbcConnectionContext) { - this( jdbcConnectionContext, new SqlExceptionHelper( true ) ); - } - - public GenerationTargetToDatabase(JdbcConnectionContext jdbcConnectionContext, SqlExceptionHelper sqlExceptionHelper) { - this.jdbcConnectionContext = jdbcConnectionContext; - this.sqlExceptionHelper = sqlExceptionHelper; + public GenerationTargetToDatabase(DdlTransactionIsolator ddlTransactionIsolator) { + this.ddlTransactionIsolator = ddlTransactionIsolator; } @Override public void prepare() { + ddlTransactionIsolator.prepare(); } @Override public void accept(String command) { - try { - jdbcConnectionContext.logSqlStatement( command ); + ddlTransactionIsolator.getJdbcContext().getSqlStatementLogger().logStatement( + command, + DDLFormatterImpl.INSTANCE + ); + try { final Statement jdbcStatement = jdbcStatement(); jdbcStatement.execute( command ); + try { SQLWarning warnings = jdbcStatement.getWarnings(); if ( warnings != null) { - sqlExceptionHelper.logAndClearWarnings( jdbcStatement ); + ddlTransactionIsolator.getJdbcContext().getSqlExceptionHelper().logAndClearWarnings( jdbcStatement ); } } catch( SQLException e ) { @@ -61,22 +60,19 @@ public class GenerationTargetToDatabase implements GenerationTarget { } catch (SQLException e) { throw new CommandAcceptanceException( - "Unable to execute command [" + command + "]", + "Error executing DDL via JDBC Statement", e ); } } - protected Statement jdbcStatement() { + private Statement jdbcStatement() { if ( jdbcStatement == null ) { try { - jdbcStatement = jdbcConnectionContext.getConnection().createStatement(); + this.jdbcStatement = ddlTransactionIsolator.getIsolatedConnection().createStatement(); } catch (SQLException e) { - throw new SchemaManagementException( - "Unable to create JDBC Statement for schema management target", - e - ); + throw ddlTransactionIsolator.getJdbcContext().getSqlExceptionHelper().convert( e, "Unable to create JDBC Statement for DDL execution" ); } } @@ -85,16 +81,6 @@ public class GenerationTargetToDatabase implements GenerationTarget { @Override public void release() { - if ( jdbcStatement != null ) { - try { - jdbcStatement.close(); - } - catch (SQLException e) { - log.debug( "Unable to close JDBC statement afterQuery JPA schema generation : " + e.toString() ); - } - } - jdbcStatement = null; - - jdbcConnectionContext.release(); + ddlTransactionIsolator.release(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedDatabaseInformationImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedDatabaseInformationImpl.java index 44228f02cc..5e2c4a634c 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedDatabaseInformationImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedDatabaseInformationImpl.java @@ -15,6 +15,7 @@ import org.hibernate.boot.model.relational.Namespace; import org.hibernate.boot.model.relational.QualifiedSequenceName; import org.hibernate.boot.model.relational.QualifiedTableName; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl; import org.hibernate.tool.schema.extract.spi.DatabaseInformation; @@ -37,14 +38,14 @@ public class ImprovedDatabaseInformationImpl public ImprovedDatabaseInformationImpl( ServiceRegistry serviceRegistry, JdbcEnvironment jdbcEnvironment, - JdbcConnectionContext connectionContext, + DdlTransactionIsolator ddlTransactionIsolator, Namespace.Name defaultNamespace) throws SQLException { this.jdbcEnvironment = jdbcEnvironment; this.extractionContext = new ImprovedExtractionContextImpl( serviceRegistry, jdbcEnvironment, - connectionContext, + ddlTransactionIsolator, defaultNamespace.getCatalog(), defaultNamespace.getSchema(), this diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedExtractionContextImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedExtractionContextImpl.java index 715b63b1f3..4df98cf501 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedExtractionContextImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/ImprovedExtractionContextImpl.java @@ -12,6 +12,7 @@ import java.sql.SQLException; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; +import org.hibernate.resource.transaction.spi.DdlTransactionIsolator; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.schema.extract.spi.ExtractionContext; @@ -21,7 +22,7 @@ import org.hibernate.tool.schema.extract.spi.ExtractionContext; public class ImprovedExtractionContextImpl implements ExtractionContext { private final ServiceRegistry serviceRegistry; private final JdbcEnvironment jdbcEnvironment; - private final JdbcConnectionContext connectionContext; + private final DdlTransactionIsolator ddlTransactionIsolator; private final Identifier defaultCatalog; private final Identifier defaultSchema; @@ -32,13 +33,13 @@ public class ImprovedExtractionContextImpl implements ExtractionContext { public ImprovedExtractionContextImpl( ServiceRegistry serviceRegistry, JdbcEnvironment jdbcEnvironment, - JdbcConnectionContext connectionContext, + DdlTransactionIsolator ddlTransactionIsolator, Identifier defaultCatalog, Identifier defaultSchema, DatabaseObjectAccess databaseObjectAccess) { this.serviceRegistry = serviceRegistry; this.jdbcEnvironment = jdbcEnvironment; - this.connectionContext = connectionContext; + this.ddlTransactionIsolator = ddlTransactionIsolator; this.defaultCatalog = defaultCatalog; this.defaultSchema = defaultSchema; this.databaseObjectAccess = databaseObjectAccess; @@ -56,7 +57,7 @@ public class ImprovedExtractionContextImpl implements ExtractionContext { @Override public Connection getJdbcConnection() { - return connectionContext.getConnection(); + return ddlTransactionIsolator.getIsolatedConnection(); } @Override @@ -96,6 +97,6 @@ public class ImprovedExtractionContextImpl implements ExtractionContext { jdbcDatabaseMetaData = null; } - connectionContext.release(); + ddlTransactionIsolator.release(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContext.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContext.java deleted file mode 100644 index 4900f2a852..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContext.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.tool.schema.internal.exec; - -import java.sql.Connection; - -/** - * JDBC-based specialization of the DataStoreConnectionContext contract. - * - * @author Steve Ebersole - */ -public interface JdbcConnectionContext { - Connection getConnection(); - - void logSqlStatement(String sqlStatement); - - void release(); -} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextNonSharedImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextNonSharedImpl.java deleted file mode 100644 index 702994a48b..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextNonSharedImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.tool.schema.internal.exec; - -import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; - -/** - * @author Steve Ebersole - */ -public class JdbcConnectionContextNonSharedImpl extends AbstractJdbcConnectionContextImpl { - public JdbcConnectionContextNonSharedImpl( - JdbcConnectionAccess jdbcConnectionAccess, - SqlStatementLogger sqlStatementLogger, - boolean needsAutoCommit) { - super( jdbcConnectionAccess, sqlStatementLogger, needsAutoCommit ); - } - - @Override - public void release() { - // for non-shared JdbcConnectionContext instances it is safe to really - // release them as part of the normal source/target cleanup call stack - reallyRelease(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextSharedImpl.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextSharedImpl.java deleted file mode 100644 index 5c3cc19ad5..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcConnectionContextSharedImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 . - */ -package org.hibernate.tool.schema.internal.exec; - -import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; - -/** - * @author Steve Ebersole - */ -public class JdbcConnectionContextSharedImpl extends AbstractJdbcConnectionContextImpl { - public JdbcConnectionContextSharedImpl( - JdbcConnectionAccess jdbcConnectionAccess, - SqlStatementLogger sqlStatementLogger, - boolean needsAutoCommit) { - super( jdbcConnectionAccess, sqlStatementLogger, needsAutoCommit ); - } - - @Override - public void release() { - // for a shared JdbcConnectionContext do not release it as part of the normal - // source/target cleanup call stacks. The creator will explicitly close the - // shared JdbcConnectionContext via #reallyRelease - } - - @Override - public void reallyRelease() { - super.reallyRelease(); - } -} diff --git a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcContext.java b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcContext.java index c8efd7687c..184e37b774 100644 --- a/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcContext.java +++ b/hibernate-core/src/main/java/org/hibernate/tool/schema/internal/exec/JdbcContext.java @@ -8,13 +8,19 @@ package org.hibernate.tool.schema.internal.exec; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.service.ServiceRegistry; /** + * Access to JDBC context for schema tooling activity. + * * @author Steve Ebersole */ public interface JdbcContext { JdbcConnectionAccess getJdbcConnectionAccess(); Dialect getDialect(); SqlStatementLogger getSqlStatementLogger(); + SqlExceptionHelper getSqlExceptionHelper(); + ServiceRegistry getServiceRegistry(); } diff --git a/hibernate-core/src/test/java/org/hibernate/test/connections/SuppliedConnectionTest.java b/hibernate-core/src/test/java/org/hibernate/test/connections/SuppliedConnectionTest.java index 16e440b8fb..94aa5bec94 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/connections/SuppliedConnectionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/connections/SuppliedConnectionTest.java @@ -18,18 +18,16 @@ import org.hibernate.cfg.Environment; import org.hibernate.dialect.H2Dialect; import org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.service.spi.Stoppable; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; import org.hibernate.tool.schema.internal.SchemaDropperImpl; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessProvidedConnectionImpl; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; import org.hibernate.testing.RequiresDialect; import org.hibernate.testing.env.ConnectionProviderBuilder; +import org.hibernate.test.util.DdlTransactionIsolatorTestingImpl; /** * Implementation of SuppliedConnectionTest. @@ -120,11 +118,7 @@ public class SuppliedConnectionTest extends ConnectionManagementTestCase { try { final GenerationTargetToDatabase target = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessProvidedConnectionImpl( conn ), - new SqlStatementLogger( false, true ), - true - ) + new DdlTransactionIsolatorTestingImpl( serviceRegistry(), conn ) ); new SchemaCreatorImpl( serviceRegistry() ).doCreation( metadata(), @@ -148,10 +142,9 @@ public class SuppliedConnectionTest extends ConnectionManagementTestCase { try { final GenerationTargetToDatabase target = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessProvidedConnectionImpl( conn ), - new SqlStatementLogger( false, true ), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry(), + conn ) ); new SchemaDropperImpl( serviceRegistry() ).doDrop( metadata(), false, target ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java index b33d969e83..59c0865a8f 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/multitenancy/schema/SchemaBasedMultiTenancyTest.java @@ -21,7 +21,6 @@ import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionPro import org.hibernate.engine.jdbc.connections.spi.AbstractMultiTenantConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.mapping.RootClass; import org.hibernate.service.spi.ServiceRegistryImplementor; @@ -29,13 +28,12 @@ import org.hibernate.tool.schema.internal.HibernateSchemaManagementTool; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; import org.hibernate.tool.schema.internal.SchemaDropperImpl; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.testing.RequiresDialectFeature; -import org.hibernate.testing.boot.JdbcConnectionAccessImpl; import org.hibernate.testing.cache.CachingRegionFactory; import org.hibernate.testing.env.ConnectionProviderBuilder; import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.test.util.DdlTransactionIsolatorTestingImpl; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -78,17 +76,15 @@ public class SchemaBasedMultiTenancyTest extends BaseUnitTestCase { tool.injectServices( serviceRegistry ); final GenerationTargetToDatabase acmeTarget = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( acmeProvider ), - new SqlStatementLogger( false, true ), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + acmeProvider ) ); final GenerationTargetToDatabase jbossTarget = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( jbossProvider ), - new SqlStatementLogger( false, true ), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + jbossProvider ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/quote/TableGeneratorQuotingTest.java b/hibernate-core/src/test/java/org/hibernate/test/quote/TableGeneratorQuotingTest.java index bdd0d2cfc4..e6ef1a0a17 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/quote/TableGeneratorQuotingTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/quote/TableGeneratorQuotingTest.java @@ -20,16 +20,15 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator; -import org.hibernate.engine.jdbc.spi.JdbcServices; import org.hibernate.tool.hbm2ddl.SchemaValidator; import org.hibernate.tool.schema.internal.SchemaCreatorImpl; import org.hibernate.tool.schema.internal.SchemaDropperImpl; import org.hibernate.tool.schema.internal.exec.GenerationTarget; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.testing.TestForIssue; import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.test.util.DdlTransactionIsolatorTestingImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -63,10 +62,9 @@ public class TableGeneratorQuotingTest extends BaseUnitTestCase { final ConnectionProvider connectionProvider = serviceRegistry.getService( ConnectionProvider.class ); final GenerationTarget target = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcEnvironmentInitiator.ConnectionProviderJdbcConnectionAccess( connectionProvider ), - serviceRegistry.getService( JdbcServices.class ).getSqlStatementLogger(), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + new JdbcEnvironmentInitiator.ConnectionProviderJdbcConnectionAccess( connectionProvider ) ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/tool/schema/DropSchemaDuringJtaTxnTest.java b/hibernate-core/src/test/java/org/hibernate/test/tool/schema/DropSchemaDuringJtaTxnTest.java new file mode 100644 index 0000000000..e432310f64 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/tool/schema/DropSchemaDuringJtaTxnTest.java @@ -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 . + */ +package org.hibernate.test.tool.schema; + +import java.util.HashMap; +import java.util.Map; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.SessionFactory; +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Environment; + +import org.hibernate.testing.jta.TestingJtaBootstrap; +import org.hibernate.testing.junit4.BaseUnitTestCase; +import org.hibernate.test.resource.transaction.jta.JtaPlatformStandardTestingImpl; +import org.junit.Test; + +/** + * @author Steve Ebersole + */ +public class DropSchemaDuringJtaTxnTest extends BaseUnitTestCase { + @Test + public void testDrop() throws Exception { + final SessionFactory sessionFactory = buildSessionFactory(); + sessionFactory.close(); + } + @Test + public void testDropDuringActiveJtaTransaction() throws Exception { + final SessionFactory sessionFactory = buildSessionFactory(); + + JtaPlatformStandardTestingImpl.INSTANCE.transactionManager().begin(); + try { + sessionFactory.close(); + } + finally { + JtaPlatformStandardTestingImpl.INSTANCE.transactionManager().commit(); + } + } + + private SessionFactory buildSessionFactory() { + Map settings = new HashMap(); + settings.putAll( Environment.getProperties() ); + TestingJtaBootstrap.prepare( settings ); + settings.put( AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY, "jta" ); + + final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder().applySettings( settings ).build(); + + return new MetadataSources( ssr ) + .addAnnotatedClass( TestEntity.class ) + .buildMetadata() + .buildSessionFactory(); + } + + + @Entity( name = "TestEntity" ) + @Table( name = "TestEntity" ) + public static class TestEntity { + @Id + public Integer id; + String name; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/tool/schema/SchemaValidatorImplTest.java b/hibernate-core/src/test/java/org/hibernate/test/tool/schema/SchemaValidatorImplTest.java index 53716bf269..2aa69b8d83 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/tool/schema/SchemaValidatorImplTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/tool/schema/SchemaValidatorImplTest.java @@ -24,7 +24,6 @@ import org.hibernate.boot.spi.MetadataImplementor; import org.hibernate.dialect.H2Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; -import org.hibernate.engine.jdbc.spi.SqlStatementLogger; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl; @@ -33,7 +32,6 @@ import org.hibernate.tool.schema.internal.SchemaCreatorImpl; import org.hibernate.tool.schema.internal.SchemaDropperImpl; import org.hibernate.tool.schema.internal.SchemaValidatorImpl; import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase; -import org.hibernate.tool.schema.internal.exec.JdbcConnectionContextNonSharedImpl; import org.hibernate.tool.schema.spi.ExceptionHandler; import org.hibernate.tool.schema.spi.ExecutionOptions; import org.hibernate.tool.schema.spi.SchemaManagementException; @@ -44,6 +42,7 @@ import org.hibernate.testing.TestForIssue; import org.hibernate.testing.boot.JdbcConnectionAccessImpl; import org.hibernate.testing.junit4.BaseUnitTestCase; import org.hibernate.testing.logger.LoggerInspectionRule; +import org.hibernate.test.util.DdlTransactionIsolatorTestingImpl; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -157,10 +156,9 @@ public class SchemaValidatorImplTest extends BaseUnitTestCase { connectionProvider.configure( properties() ); final GenerationTargetToDatabase schemaGenerator = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( connectionProvider ), - new SqlStatementLogger( false, true ), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + new JdbcConnectionAccessImpl( connectionProvider ) ) ); @@ -213,10 +211,9 @@ public class SchemaValidatorImplTest extends BaseUnitTestCase { connectionProvider.configure( properties() ); final GenerationTargetToDatabase schemaGenerator = new GenerationTargetToDatabase( - new JdbcConnectionContextNonSharedImpl( - new JdbcConnectionAccessImpl( connectionProvider ), - new SqlStatementLogger( false, true ), - true + new DdlTransactionIsolatorTestingImpl( + serviceRegistry, + new JdbcConnectionAccessImpl( connectionProvider ) ) ); diff --git a/hibernate-core/src/test/java/org/hibernate/test/util/DdlTransactionIsolatorTestingImpl.java b/hibernate-core/src/test/java/org/hibernate/test/util/DdlTransactionIsolatorTestingImpl.java new file mode 100644 index 0000000000..241f00396c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/util/DdlTransactionIsolatorTestingImpl.java @@ -0,0 +1,74 @@ +package org.hibernate.test.util; + +import java.sql.Connection; + +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; +import org.hibernate.engine.jdbc.spi.JdbcServices; +import org.hibernate.engine.jdbc.spi.SqlExceptionHelper; +import org.hibernate.engine.jdbc.spi.SqlStatementLogger; +import org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl; +import org.hibernate.service.ServiceRegistry; +import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessConnectionProviderImpl; +import org.hibernate.tool.schema.internal.exec.JdbcConnectionAccessProvidedConnectionImpl; +import org.hibernate.tool.schema.internal.exec.JdbcContext; + +/** + * @author Steve Ebersole + */ +public class DdlTransactionIsolatorTestingImpl extends DdlTransactionIsolatorNonJtaImpl { + public DdlTransactionIsolatorTestingImpl(ServiceRegistry serviceRegistry, Connection jdbConnection) { + this( serviceRegistry, createJdbcConnectionAccess( jdbConnection ) ); + } + + public static JdbcConnectionAccess createJdbcConnectionAccess(Connection jdbcConnection) { + return new JdbcConnectionAccessProvidedConnectionImpl( jdbcConnection ); + } + + public DdlTransactionIsolatorTestingImpl(ServiceRegistry serviceRegistry, JdbcConnectionAccess jdbcConnectionAccess) { + super( createJdbcContext( jdbcConnectionAccess, serviceRegistry ) ); + } + + public static JdbcContext createJdbcContext( + JdbcConnectionAccess jdbcConnectionAccess, + ServiceRegistry serviceRegistry) { + return new JdbcContext() { + final JdbcServices jdbcServices = serviceRegistry.getService( JdbcServices.class ); + + @Override + public JdbcConnectionAccess getJdbcConnectionAccess() { + return jdbcConnectionAccess; + } + + @Override + public Dialect getDialect() { + return jdbcServices.getJdbcEnvironment().getDialect(); + } + + @Override + public SqlStatementLogger getSqlStatementLogger() { + return jdbcServices.getSqlStatementLogger(); + } + + @Override + public SqlExceptionHelper getSqlExceptionHelper() { + return jdbcServices.getSqlExceptionHelper(); + } + + @Override + public ServiceRegistry getServiceRegistry() { + return serviceRegistry; + } + }; + } + + public DdlTransactionIsolatorTestingImpl(ServiceRegistry serviceRegistry, ConnectionProvider connectionProvider) { + this( serviceRegistry, createJdbcConnectionAccess( connectionProvider ) ); + } + + private static JdbcConnectionAccess createJdbcConnectionAccess(ConnectionProvider connectionProvider) { + return new JdbcConnectionAccessConnectionProviderImpl( connectionProvider ); + } + +}