From 5b2289e883fb022beaf1c0dcb6097cd69463e399 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Thu, 10 Jun 2021 12:05:32 +0100 Subject: [PATCH] HHH-14667 Avoid triggering the load of sequence metadata when not required Also introduce SequenceMismatchStrategy#NONE, which allows to fully disable the checks performed by SequenceMismatchStrategy on initialization; combining these two changes, users have the option to fully skip loading the details about existing sequences from the DB. --- .../userguide/appendices/Configurations.adoc | 2 +- .../org/hibernate/cfg/AvailableSettings.java | 5 +- .../ExtractedDatabaseMetaDataImpl.java | 98 ++++++++++++++++--- .../env/internal/JdbcEnvironmentImpl.java | 60 +++--------- .../internal/JdbcEnvironmentInitiator.java | 3 +- .../id/SequenceMismatchStrategy.java | 8 +- .../id/enhanced/SequenceStyleGenerator.java | 16 +-- .../SkipLoadingSequenceInformationTest.java | 71 ++++++++++++++ ...LServerDialectSequenceInformationTest.java | 10 +- .../test/schemafilter/SequenceFilterTest.java | 1 + .../boot/BasicTestingJdbcServiceImpl.java | 4 +- 11 files changed, 199 insertions(+), 79 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/engine/jdbc/env/internal/SkipLoadingSequenceInformationTest.java diff --git a/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc index 333409606e..3f608e0b55 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Configurations.adoc @@ -275,7 +275,7 @@ Please report your mapping that causes the problem to us so we can examine the d + The default value is `false` which means Hibernate will use an algorithm to determine if the insert can be delayed or if the insert should be performed immediately. -`*hibernate.id.sequence.increment_size_mismatch_strategy*` (e.g. `LOG`, `FIX` or `EXCEPTION` (default value)):: +`*hibernate.id.sequence.increment_size_mismatch_strategy*` (e.g. `LOG`, `FIX`, `NONE` or `EXCEPTION` (default value)):: This setting defines the `org.hibernate.id.SequenceMismatchStrategy` used when Hibernate detects a mismatch between a sequence configuration in an entity mapping and its database sequence object counterpart. diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index b7efa75376..51e765ebd0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -2423,8 +2423,9 @@ public interface AvailableSettings extends org.hibernate.jpa.AvailableSettings { * and its database sequence object counterpart. *

* Possible values are {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, - * {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, and - * {@link org.hibernate.id.SequenceMismatchStrategy#FIX}. + * {@link org.hibernate.id.SequenceMismatchStrategy#LOG}, + * {@link org.hibernate.id.SequenceMismatchStrategy#FIX} + * and {@link org.hibernate.id.SequenceMismatchStrategy#NONE}. *

* The default value is given by the {@link org.hibernate.id.SequenceMismatchStrategy#EXCEPTION}, * meaning that an Exception is thrown when detecting such a conflict. diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/ExtractedDatabaseMetaDataImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/ExtractedDatabaseMetaDataImpl.java index 18a40d684c..1ac0389086 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/ExtractedDatabaseMetaDataImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/ExtractedDatabaseMetaDataImpl.java @@ -6,18 +6,25 @@ */ package org.hibernate.engine.jdbc.env.internal; +import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import org.hibernate.HibernateException; import org.hibernate.boot.model.source.internal.hbm.CommaSeparatedStringHelper; +import org.hibernate.dialect.Dialect; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.cursor.internal.StandardRefCursorSupport; import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.env.spi.SQLStateType; +import org.hibernate.tool.schema.extract.spi.ExtractionContext; import org.hibernate.tool.schema.extract.spi.SequenceInformation; /** @@ -26,7 +33,9 @@ import org.hibernate.tool.schema.extract.spi.SequenceInformation; * @author Steve Ebersole */ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData { + private final JdbcEnvironment jdbcEnvironment; + private final JdbcConnectionAccess connectionAccess; private final String connectionCatalogName; private final String connectionSchemaName; @@ -39,11 +48,16 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData private final boolean supportsDataDefinitionInTransaction; private final boolean doesDataDefinitionCauseTransactionCommit; private final SQLStateType sqlStateType; + private final boolean jdbcMetadataAccessible; - private final List sequenceInformationList; + //Lazily initialized: loading all sequence information upfront has been + //shown to be too slow in some cases. In this way we only load it + //when there is actual need for these details. + private List sequenceInformationList; private ExtractedDatabaseMetaDataImpl( JdbcEnvironment jdbcEnvironment, + JdbcConnectionAccess connectionAccess, String connectionCatalogName, String connectionSchemaName, boolean supportsRefCursors, @@ -54,8 +68,9 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData boolean supportsDataDefinitionInTransaction, boolean doesDataDefinitionCauseTransactionCommit, SQLStateType sqlStateType, - List sequenceInformationList) { + boolean jdbcMetadataIsAccessible) { this.jdbcEnvironment = jdbcEnvironment; + this.connectionAccess = connectionAccess; this.connectionCatalogName = connectionCatalogName; this.connectionSchemaName = connectionSchemaName; this.supportsRefCursors = supportsRefCursors; @@ -66,7 +81,7 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction; this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit; this.sqlStateType = sqlStateType; - this.sequenceInformationList = sequenceInformationList; + this.jdbcMetadataAccessible = jdbcMetadataIsAccessible; } @Override @@ -125,12 +140,26 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData } @Override - public List getSequenceInformationList() { - return sequenceInformationList; + public synchronized List getSequenceInformationList() { + if ( jdbcMetadataAccessible ) { + //Loading the sequence information can take a while on large databases, + //even minutes in some cases. + //We trigger this lazily as only certain combinations of configurations, + //mappings and used features actually trigger any use of such details. + if ( sequenceInformationList == null ) { + sequenceInformationList = sequenceInformationList(); + } + return sequenceInformationList; + } + else { + return Collections.emptyList(); + } } public static class Builder { private final JdbcEnvironment jdbcEnvironment; + private final boolean jdbcMetadataIsAccessible; + private final JdbcConnectionAccess connectionAccess; private String connectionSchemaName; private String connectionCatalogName; @@ -143,10 +172,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData private boolean supportsDataDefinitionInTransaction; private boolean doesDataDefinitionCauseTransactionCommit; private SQLStateType sqlStateType; - private List sequenceInformationList = Collections.emptyList(); - public Builder(JdbcEnvironment jdbcEnvironment) { + public Builder(JdbcEnvironment jdbcEnvironment, boolean jdbcMetadataIsAccessible, JdbcConnectionAccess connectionAccess) { this.jdbcEnvironment = jdbcEnvironment; + this.jdbcMetadataIsAccessible = jdbcMetadataIsAccessible; + this.connectionAccess = connectionAccess; } public Builder apply(DatabaseMetaData databaseMetaData) throws SQLException { @@ -217,14 +247,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData return this; } - public Builder setSequenceInformationList(List sequenceInformationList) { - this.sequenceInformationList = sequenceInformationList; - return this; - } - public ExtractedDatabaseMetaDataImpl build() { return new ExtractedDatabaseMetaDataImpl( jdbcEnvironment, + connectionAccess, connectionCatalogName, connectionSchemaName, supportsRefCursors, @@ -235,8 +261,54 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData supportsDataDefinitionInTransaction, doesDataDefinitionCauseTransactionCommit, sqlStateType, - sequenceInformationList + jdbcMetadataIsAccessible ); } } + + /** + * Get the sequence information List from the database. + * + * @return sequence information List + */ + private List sequenceInformationList() { + final JdbcEnvironment jdbcEnvironment = this.jdbcEnvironment; + final Dialect dialect = this.jdbcEnvironment.getDialect(); + + Connection connection = null; + try { + connection = connectionAccess.obtainConnection(); + final Connection c = connection; + Iterable sequenceInformationIterable = dialect + .getSequenceInformationExtractor() + .extractMetadata( new ExtractionContext.EmptyExtractionContext() { + @Override + public Connection getJdbcConnection() { + return c; + } + + @Override + public JdbcEnvironment getJdbcEnvironment() { + return jdbcEnvironment; + } + } + ); + return StreamSupport.stream( sequenceInformationIterable.spliterator(), false ) + .collect( Collectors.toList() ); + } + catch (SQLException e) { + throw new HibernateException( "Could not fetch the SequenceInformation from the database", e ); + } + finally { + if ( connection != null ) { + try { + connectionAccess.releaseConnection( connection ); + } + catch (SQLException throwables) { + //ignored + } + } + } + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java index e6fdf2d4a0..ab55ef3d46 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentImpl.java @@ -6,13 +6,8 @@ */ package org.hibernate.engine.jdbc.env.internal; -import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.registry.selector.spi.StrategySelector; @@ -20,6 +15,7 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.dialect.Dialect; import org.hibernate.engine.config.spi.ConfigurationService; import org.hibernate.engine.config.spi.StandardConverters; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData; import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder; @@ -35,8 +31,6 @@ import org.hibernate.exception.internal.SQLStateConversionDelegate; import org.hibernate.exception.internal.StandardSQLExceptionConverter; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.spi.ServiceRegistryImplementor; -import org.hibernate.tool.schema.extract.spi.ExtractionContext; -import org.hibernate.tool.schema.extract.spi.SequenceInformation; import org.jboss.logging.Logger; @@ -64,7 +58,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { * @param serviceRegistry The service registry * @param dialect The resolved dialect. */ - public JdbcEnvironmentImpl(final ServiceRegistryImplementor serviceRegistry, Dialect dialect) { + public JdbcEnvironmentImpl(final ServiceRegistryImplementor serviceRegistry, final Dialect dialect) { this.dialect = dialect; final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class ); @@ -86,7 +80,7 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { identifierHelperBuilder.setNameQualifierSupport( nameQualifierSupport ); IdentifierHelper identifierHelper = null; - ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = new ExtractedDatabaseMetaDataImpl.Builder( this ); + ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = new ExtractedDatabaseMetaDataImpl.Builder( this, false, null ); try { identifierHelper = dialect.buildIdentifierHelper( identifierHelperBuilder, null ); dbMetaDataBuilder.setSupportsNamedParameters( dialect.supportsNamedParameters( null ) ); @@ -150,8 +144,12 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { * Constructor form used from testing * * @param dialect The dialect + * @param jdbcConnectionAccess */ - public JdbcEnvironmentImpl(DatabaseMetaData databaseMetaData, Dialect dialect) throws SQLException { + public JdbcEnvironmentImpl( + DatabaseMetaData databaseMetaData, + Dialect dialect, + JdbcConnectionAccess jdbcConnectionAccess) throws SQLException { this.dialect = dialect; this.sqlExceptionHelper = buildSqlExceptionHelper( dialect, false ); @@ -177,10 +175,9 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { } this.identifierHelper = identifierHelper; - this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ) + this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this, true, jdbcConnectionAccess ) .apply( databaseMetaData ) .setSupportsNamedParameters( databaseMetaData.supportsNamedParameters() ) - .setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) ) .build(); this.currentCatalog = null; @@ -224,7 +221,8 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { public JdbcEnvironmentImpl( ServiceRegistryImplementor serviceRegistry, Dialect dialect, - DatabaseMetaData databaseMetaData) throws SQLException { + DatabaseMetaData databaseMetaData, + JdbcConnectionAccess jdbcConnectionAccess) throws SQLException { this.dialect = dialect; final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class ); @@ -256,11 +254,10 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { } this.identifierHelper = identifierHelper; - this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this ) + this.extractedMetaDataSupport = new ExtractedDatabaseMetaDataImpl.Builder( this, true, jdbcConnectionAccess ) .apply( databaseMetaData ) .setConnectionSchemaName( determineCurrentSchemaName( databaseMetaData, serviceRegistry, dialect ) ) .setSupportsNamedParameters( dialect.supportsNamedParameters( databaseMetaData ) ) - .setSequenceInformationList( sequenceInformationList( databaseMetaData.getConnection() ) ) .build(); // and that current-catalog and current-schema happen after it @@ -369,37 +366,4 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment { " Use org.hibernate.engine.jdbc.spi.TypeInfo.extractTypeInfo as alternative, or report an issue and explain." ); } - /** - * Get the sequence information List from the database. - * - * @param connection database connection - * @return sequence information List - */ - private List sequenceInformationList(final Connection connection) { - try { - - Iterable sequenceInformationIterable = dialect - .getSequenceInformationExtractor() - .extractMetadata( new ExtractionContext.EmptyExtractionContext() { - @Override - public Connection getJdbcConnection() { - return connection; - } - - @Override - public JdbcEnvironment getJdbcEnvironment() { - return JdbcEnvironmentImpl.this; - } - } - ); - - return StreamSupport.stream( sequenceInformationIterable.spliterator(), false ) - .collect( Collectors.toList() ); - } - catch (SQLException e) { - log.error( "Could not fetch the SequenceInformation from the database", e ); - } - - return Collections.emptyList(); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java index d2563e4251..edf0f769d9 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/env/internal/JdbcEnvironmentInitiator.java @@ -114,7 +114,8 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator. + */ +package org.hibernate.engine.jdbc.env.internal; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.hibernate.annotations.GenericGenerator; +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.id.SequenceMismatchStrategy; +import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor; + +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +/** + * Verifies that setting {@code AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY} to {@code none} + * is going to skip loading the sequence information from the database. + */ +@TestForIssue( jiraKey = "HHH-14667") +public class SkipLoadingSequenceInformationTest extends BaseCoreFunctionalTestCase { + + @Override + protected void configure(Configuration configuration) { + configuration.setProperty( AvailableSettings.SEQUENCE_INCREMENT_SIZE_MISMATCH_STRATEGY, SequenceMismatchStrategy.NONE.name() ); + configuration.setProperty( Environment.DIALECT, VetoingDialect.class.getName() ); + } + + @Entity(name="seqentity") + static class SequencingEntity { + @Id + @GenericGenerator(name = "pooledoptimizer", strategy = "enhanced-sequence", + parameters = { + @org.hibernate.annotations.Parameter(name = "optimizer", value = "pooled"), + @org.hibernate.annotations.Parameter(name = "initial_value", value = "1"), + @org.hibernate.annotations.Parameter(name = "increment_size", value = "2") + } + ) + @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "pooledoptimizer") + Integer id; + String name; + } + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[]{SequencingEntity.class}; + } + + @Test + public void test() { + // If it's able to boot, we're good. + } + + public static class VetoingDialect extends H2Dialect { + @Override + public SequenceInformationExtractor getSequenceInformationExtractor() { + throw new IllegalStateException("Should really not invoke this method in this setup"); + } + } + +} diff --git a/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectSequenceInformationTest.java b/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectSequenceInformationTest.java index 5352df7fb9..1193cf8d68 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectSequenceInformationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/dialect/functional/SQLServerDialectSequenceInformationTest.java @@ -22,6 +22,7 @@ import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.Environment; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.SQLServer2012Dialect; +import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess; import org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl; import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment; import org.hibernate.engine.jdbc.spi.JdbcServices; @@ -82,15 +83,16 @@ public class SQLServerDialectSequenceInformationTest extends BaseUnitTestCase { ssrb.applySettings( Collections.singletonMap( AvailableSettings.URL, newUrl ) ); StandardServiceRegistry ssr = ssrb.build(); - try ( Connection connection = ssr.getService( JdbcServices.class ) - .getBootstrapJdbcConnectionAccess() - .obtainConnection() ) { + final JdbcConnectionAccess bootstrapJdbcConnectionAccess = ssr.getService( JdbcServices.class ) + .getBootstrapJdbcConnectionAccess(); + + try ( Connection connection = bootstrapJdbcConnectionAccess.obtainConnection() ) { try (Statement statement = connection.createStatement()) { statement.execute( "CREATE SEQUENCE ITEM_SEQ START WITH 100 INCREMENT BY 10" ); } - JdbcEnvironment jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), dialect ); + JdbcEnvironment jdbcEnvironment = new JdbcEnvironmentImpl( connection.getMetaData(), dialect, bootstrapJdbcConnectionAccess ); Iterable sequenceInformations = SequenceInformationExtractorLegacyImpl.INSTANCE.extractMetadata( new ExtractionContext.EmptyExtractionContext() { @Override diff --git a/hibernate-core/src/test/java/org/hibernate/test/schemafilter/SequenceFilterTest.java b/hibernate-core/src/test/java/org/hibernate/test/schemafilter/SequenceFilterTest.java index e794cd28b3..fd80567369 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/schemafilter/SequenceFilterTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/schemafilter/SequenceFilterTest.java @@ -62,6 +62,7 @@ public class SequenceFilterTest extends BaseUnitTestCase { Map settings = new HashMap(); settings.putAll( Environment.getProperties() ); settings.put( AvailableSettings.DIALECT, H2Dialect.class.getName() ); + settings.put( "hibernate.temp.use_jdbc_metadata_defaults", "false" ); settings.put( AvailableSettings.FORMAT_SQL, false ); this.serviceRegistry = ServiceRegistryBuilder.buildServiceRegistry( settings ); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/boot/BasicTestingJdbcServiceImpl.java b/hibernate-testing/src/main/java/org/hibernate/testing/boot/BasicTestingJdbcServiceImpl.java index 836c3f50c8..c3ade8b0a1 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/boot/BasicTestingJdbcServiceImpl.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/boot/BasicTestingJdbcServiceImpl.java @@ -58,10 +58,11 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices, ServiceRegistr dialect = ConnectionProviderBuilder.getCorrespondingDialect(); connectionProvider = ConnectionProviderBuilder.buildConnectionProvider( allowAggressiveRelease ); sqlStatementLogger = new SqlStatementLogger( true, false, false ); + this.jdbcConnectionAccess = new JdbcConnectionAccessImpl( connectionProvider ); Connection jdbcConnection = connectionProvider.getConnection(); try { - jdbcEnvironment = new JdbcEnvironmentImpl( jdbcConnection.getMetaData(), dialect ); + jdbcEnvironment = new JdbcEnvironmentImpl( jdbcConnection.getMetaData(), dialect, jdbcConnectionAccess ); } finally { try { @@ -71,7 +72,6 @@ public class BasicTestingJdbcServiceImpl implements JdbcServices, ServiceRegistr } } - this.jdbcConnectionAccess = new JdbcConnectionAccessImpl( connectionProvider ); } public void release() {