HHH-10896 - Exception thrown when dropping schema with a managed connection

This commit is contained in:
Steve Ebersole 2016-07-28 15:40:58 -05:00
parent 8769ab306e
commit 10def48f48
30 changed files with 627 additions and 338 deletions

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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" );
}
}
}
}

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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" );
}
}
}
}

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();
}

View File

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

View File

@ -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).
* </li>
* <li>
* 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
* </li>
* </ul>
*

View File

@ -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() {
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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 );
}
}
}
}

View File

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

View File

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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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