HHH-11542 - Allow the auto-commit resolution to be configurable for RESOURCE_LOCAL transactions
This commit is contained in:
parent
23aad981a8
commit
ca103dcb28
|
@ -54,6 +54,14 @@ Note that for backwards compatibility, if a https://docs.jboss.org/hibernate/orm
|
||||||
|`hibernate.connection.isolation` | `REPEATABLE_READ` or
|
|`hibernate.connection.isolation` | `REPEATABLE_READ` or
|
||||||
`Connection.TRANSACTION_REPEATABLE_READ` | Names the JDBC connection transaction isolation level.
|
`Connection.TRANSACTION_REPEATABLE_READ` | Names the JDBC connection transaction isolation level.
|
||||||
|`hibernate.connection.autocommit` | `true` or `false` (default value) | Names the JDBC connection autocommit mode.
|
|`hibernate.connection.autocommit` | `true` or `false` (default value) | Names the JDBC connection autocommit mode.
|
||||||
|
|`hibernate.connection.skip_autocommit_check` | `true` or `false` (default value) |
|
||||||
|
|
||||||
|
When using an external non-JTA `DataSource`, it might be that the underlying `DataSource` already disables the autocommit mode,
|
||||||
|
so there is no need to check this `Connection` attribute upon starting a RESOURCE_LOCAL transaction.
|
||||||
|
|
||||||
|
By setting it to `true`, the `Connection` acquisition can be delayed until the first SQL statement is needed to be executed.
|
||||||
|
The connection acquisition delay allows you to reduce the database connection lease time, therefore allowing you to increase the transaction throughput.
|
||||||
|
|
||||||
|`hibernate.connection.datasource` | |
|
|`hibernate.connection.datasource` | |
|
||||||
|
|
||||||
Either a `javax.sql.DataSource` instance or a JNDI name under which to locate the `DataSource`.
|
Either a `javax.sql.DataSource` instance or a JNDI name under which to locate the `DataSource`.
|
||||||
|
|
|
@ -342,6 +342,14 @@ public interface AvailableSettings {
|
||||||
*/
|
*/
|
||||||
String DATASOURCE ="hibernate.connection.datasource";
|
String DATASOURCE ="hibernate.connection.datasource";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instructs Hibernate to skip the autocommit check for local transactions since
|
||||||
|
* the underlying {@link javax.sql.DataSource} has already disabled autocommit.
|
||||||
|
*
|
||||||
|
* @since 5.2.10
|
||||||
|
*/
|
||||||
|
String SKIP_AUTOCOMMIT_CHECK ="hibernate.connection.skip_autocommit_check";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Names a prefix used to define arbitrary JDBC connection properties. These properties are passed along to
|
* Names a prefix used to define arbitrary JDBC connection properties. These properties are passed along to
|
||||||
* the {@literal JDBC} provider when creating a connection.
|
* the {@literal JDBC} provider when creating a connection.
|
||||||
|
|
|
@ -62,11 +62,13 @@ public abstract class AbstractLogicalConnectionImplementor implements LogicalCon
|
||||||
@Override
|
@Override
|
||||||
public void begin() {
|
public void begin() {
|
||||||
try {
|
try {
|
||||||
|
if ( !isSkipAutoCommitCheck() ) {
|
||||||
log.trace( "Preparing to begin transaction via JDBC Connection.setAutoCommit(false)" );
|
log.trace( "Preparing to begin transaction via JDBC Connection.setAutoCommit(false)" );
|
||||||
getConnectionForTransactionManagement().setAutoCommit( false );
|
getConnectionForTransactionManagement().setAutoCommit( false );
|
||||||
status = TransactionStatus.ACTIVE;
|
|
||||||
log.trace( "Transaction begun via JDBC Connection.setAutoCommit(false)" );
|
log.trace( "Transaction begun via JDBC Connection.setAutoCommit(false)" );
|
||||||
}
|
}
|
||||||
|
status = TransactionStatus.ACTIVE;
|
||||||
|
}
|
||||||
catch( SQLException e ) {
|
catch( SQLException e ) {
|
||||||
throw new TransactionException( "JDBC begin transaction failed: ", e );
|
throw new TransactionException( "JDBC begin transaction failed: ", e );
|
||||||
}
|
}
|
||||||
|
@ -136,4 +138,8 @@ public abstract class AbstractLogicalConnectionImplementor implements LogicalCon
|
||||||
public TransactionStatus getStatus(){
|
public TransactionStatus getStatus(){
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isSkipAutoCommitCheck() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@ import java.sql.SQLException;
|
||||||
import org.hibernate.ConnectionAcquisitionMode;
|
import org.hibernate.ConnectionAcquisitionMode;
|
||||||
import org.hibernate.ConnectionReleaseMode;
|
import org.hibernate.ConnectionReleaseMode;
|
||||||
import org.hibernate.ResourceClosedException;
|
import org.hibernate.ResourceClosedException;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
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.connections.spi.JdbcConnectionAccess;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
|
@ -43,6 +46,8 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
||||||
private transient Connection physicalConnection;
|
private transient Connection physicalConnection;
|
||||||
private boolean closed;
|
private boolean closed;
|
||||||
|
|
||||||
|
private boolean skipAutoCommitCheck;
|
||||||
|
|
||||||
public LogicalConnectionManagedImpl(
|
public LogicalConnectionManagedImpl(
|
||||||
JdbcConnectionAccess jdbcConnectionAccess,
|
JdbcConnectionAccess jdbcConnectionAccess,
|
||||||
JdbcSessionContext jdbcSessionContext) {
|
JdbcSessionContext jdbcSessionContext) {
|
||||||
|
@ -70,6 +75,15 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
||||||
if ( connectionHandlingMode.getAcquisitionMode() == ConnectionAcquisitionMode.IMMEDIATELY ) {
|
if ( connectionHandlingMode.getAcquisitionMode() == ConnectionAcquisitionMode.IMMEDIATELY ) {
|
||||||
acquireConnectionIfNeeded();
|
acquireConnectionIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigurationService configurationService = jdbcSessionContext.getServiceRegistry()
|
||||||
|
.getService( ConfigurationService.class );
|
||||||
|
|
||||||
|
this.skipAutoCommitCheck = configurationService.getSetting(
|
||||||
|
AvailableSettings.SKIP_AUTOCOMMIT_CHECK,
|
||||||
|
StandardConverters.BOOLEAN,
|
||||||
|
false
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PhysicalConnectionHandlingMode determineConnectionHandlingMode(
|
private PhysicalConnectionHandlingMode determineConnectionHandlingMode(
|
||||||
|
@ -251,7 +265,8 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void begin() {
|
public void begin() {
|
||||||
initiallyAutoCommit = determineInitialAutoCommitMode( getConnectionForTransactionManagement() );
|
initiallyAutoCommit = !isSkipAutoCommitCheck() && determineInitialAutoCommitMode(
|
||||||
|
getConnectionForTransactionManagement() );
|
||||||
super.begin();
|
super.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,4 +277,9 @@ public class LogicalConnectionManagedImpl extends AbstractLogicalConnectionImple
|
||||||
resetConnection( initiallyAutoCommit );
|
resetConnection( initiallyAutoCommit );
|
||||||
initiallyAutoCommit = false;
|
initiallyAutoCommit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isSkipAutoCommitCheck() {
|
||||||
|
return skipAutoCommitCheck;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,15 @@ import java.lang.reflect.Field;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
import org.hibernate.engine.config.spi.StandardConverters;
|
||||||
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
import org.hibernate.engine.jdbc.batch.spi.Batch;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
|
||||||
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
import org.hibernate.resource.jdbc.spi.JdbcObserver;
|
||||||
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
import org.hibernate.resource.jdbc.spi.JdbcSessionContext;
|
||||||
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
import org.hibernate.resource.jdbc.spi.JdbcSessionOwner;
|
||||||
|
@ -62,6 +67,12 @@ public class JdbcCoordinatorTest {
|
||||||
when( serviceRegistry.getService( eq( JdbcServices.class ) ) ).thenReturn(
|
when( serviceRegistry.getService( eq( JdbcServices.class ) ) ).thenReturn(
|
||||||
jdbcServices );
|
jdbcServices );
|
||||||
|
|
||||||
|
ConfigurationService configurationService = Mockito.mock( ConfigurationService.class );
|
||||||
|
when( serviceRegistry.getService( eq( ConfigurationService.class ) ) ).thenReturn(
|
||||||
|
configurationService );
|
||||||
|
when( configurationService.getSetting(eq( AvailableSettings.SKIP_AUTOCOMMIT_CHECK ), same( StandardConverters.BOOLEAN), eq( false )) )
|
||||||
|
.thenReturn( false );
|
||||||
|
|
||||||
SqlExceptionHelper sqlExceptionHelper = Mockito.mock( SqlExceptionHelper.class );
|
SqlExceptionHelper sqlExceptionHelper = Mockito.mock( SqlExceptionHelper.class );
|
||||||
when( jdbcServices.getSqlExceptionHelper() ).thenReturn(
|
when( jdbcServices.getSqlExceptionHelper() ).thenReturn(
|
||||||
sqlExceptionHelper );
|
sqlExceptionHelper );
|
||||||
|
|
|
@ -44,7 +44,7 @@ import static org.junit.Assert.fail;
|
||||||
@RequiresDialect(H2Dialect.class)
|
@RequiresDialect(H2Dialect.class)
|
||||||
public class CriteriaLiteralsTest extends BaseEntityManagerFunctionalTestCase {
|
public class CriteriaLiteralsTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
private PreparedStatementSpyConnectionProvider connectionProvider = new PreparedStatementSpyConnectionProvider();
|
private PreparedStatementSpyConnectionProvider connectionProvider;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map getConfig() {
|
protected Map getConfig() {
|
||||||
|
@ -56,6 +56,12 @@ public class CriteriaLiteralsTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildEntityManagerFactory() throws Exception {
|
||||||
|
connectionProvider = new PreparedStatementSpyConnectionProvider();
|
||||||
|
super.buildEntityManagerFactory();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void releaseResources() {
|
public void releaseResources() {
|
||||||
super.releaseResources();
|
super.releaseResources();
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.testing.jdbc.PreparedStatementSpyConnectionProvider;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public abstract class AbstractSkipAutoCommitTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
private PreparedStatementSpyConnectionProvider connectionProvider =
|
||||||
|
new PreparedStatementSpyConnectionProvider() {
|
||||||
|
@Override
|
||||||
|
protected Connection actualConnection() throws SQLException {
|
||||||
|
Connection connection = super.actualConnection();
|
||||||
|
connection.setAutoCommit( false );
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Map getConfig() {
|
||||||
|
Map config = super.getConfig();
|
||||||
|
|
||||||
|
config.put( AvailableSettings.DATASOURCE, dataSource() );
|
||||||
|
config.put( AvailableSettings.SKIP_AUTOCOMMIT_CHECK, Boolean.TRUE );
|
||||||
|
config.put( AvailableSettings.CONNECTION_PROVIDER, connectionProvider );
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract DataSource dataSource();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseResources() {
|
||||||
|
super.releaseResources();
|
||||||
|
connectionProvider.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
City.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
connectionProvider.clear();
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
City city = new City();
|
||||||
|
city.setId( 1L );
|
||||||
|
city.setName( "Cluj-Napoca" );
|
||||||
|
entityManager.persist( city );
|
||||||
|
|
||||||
|
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
||||||
|
assertTrue( connectionProvider.getReleasedConnections().isEmpty() );
|
||||||
|
} );
|
||||||
|
verifyConnections();
|
||||||
|
|
||||||
|
connectionProvider.clear();
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
City city = entityManager.find( City.class, 1L );
|
||||||
|
assertEquals( "Cluj-Napoca", city.getName() );
|
||||||
|
} );
|
||||||
|
verifyConnections();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyConnections() {
|
||||||
|
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
||||||
|
|
||||||
|
List<Connection> connections = connectionProvider.getReleasedConnections();
|
||||||
|
assertEquals( 1, connections.size() );
|
||||||
|
Connection connection = connections.get( 0 );
|
||||||
|
try {
|
||||||
|
verify(connection, never()).setAutoCommit( false );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "City" )
|
||||||
|
public static class City {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@RequiresDialect(H2Dialect.class)
|
||||||
|
public class H2SkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataSource dataSource() {
|
||||||
|
DataSource dataSource = ReflectionUtil.newInstance( "org.h2.jdbcx.JdbcDataSource" );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "URL", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "user", Environment.getProperties().getProperty( AvailableSettings.USER ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "password", Environment.getProperties().getProperty( AvailableSettings.PASS ) );
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
|
import org.hibernate.dialect.PostgreSQL81Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@RequiresDialect(MySQLDialect.class)
|
||||||
|
public class MySQLSkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataSource dataSource() {
|
||||||
|
DataSource dataSource = ReflectionUtil.newInstance( "com.mysql.cj.jdbc.MysqlDataSource" );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "url", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "user", Environment.getProperties().getProperty( AvailableSettings.USER ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "password", Environment.getProperties().getProperty( AvailableSettings.PASS ) );
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.MySQLDialect;
|
||||||
|
import org.hibernate.dialect.Oracle8iDialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@RequiresDialect(Oracle8iDialect.class)
|
||||||
|
public class OracleSkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataSource dataSource() {
|
||||||
|
DataSource dataSource = ReflectionUtil.newInstance( "oracle.jdbc.pool.OracleDataSource" );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "URL", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "user", Environment.getProperties().getProperty( AvailableSettings.USER ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "password", Environment.getProperties().getProperty( AvailableSettings.PASS ) );
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.dialect.PostgreSQL81Dialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@RequiresDialect(PostgreSQL81Dialect.class)
|
||||||
|
public class PostgreSQLSkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataSource dataSource() {
|
||||||
|
DataSource dataSource = ReflectionUtil.newInstance( "org.postgresql.ds.PGSimpleDataSource" );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "url", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "user", Environment.getProperties().getProperty( AvailableSettings.USER ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "password", Environment.getProperties().getProperty( AvailableSettings.PASS ) );
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc.autocommit;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Environment;
|
||||||
|
import org.hibernate.dialect.PostgreSQL81Dialect;
|
||||||
|
import org.hibernate.dialect.SQLServerDialect;
|
||||||
|
|
||||||
|
import org.hibernate.testing.RequiresDialect;
|
||||||
|
import org.hibernate.test.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
@RequiresDialect(SQLServerDialect.class)
|
||||||
|
public class SQLServerSkipAutoCommitTest extends AbstractSkipAutoCommitTest {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataSource dataSource() {
|
||||||
|
DataSource dataSource = ReflectionUtil.newInstance( "com.microsoft.sqlserver.jdbc.SQLServerDataSource" );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "URL", Environment.getProperties().getProperty( AvailableSettings.URL ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "user", Environment.getProperties().getProperty( AvailableSettings.USER ) );
|
||||||
|
ReflectionUtil.setProperty( dataSource, "password", Environment.getProperties().getProperty( AvailableSettings.PASS ) );
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package org.hibernate.test.util;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,6 +63,22 @@ public class ReflectionUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set target Object field to a certain value
|
||||||
|
* @param target Object whose field is being set
|
||||||
|
* @param fieldName Object field naem to set
|
||||||
|
* @param value the new value for the given field
|
||||||
|
*/
|
||||||
|
public static void setField(Object target, String fieldName, Object value) {
|
||||||
|
try {
|
||||||
|
Field field = getField(target.getClass(), fieldName);
|
||||||
|
field.set( target, value );
|
||||||
|
}
|
||||||
|
catch ( IllegalAccessException e ) {
|
||||||
|
throw new IllegalArgumentException("Field " + fieldName + " could not be set", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* New target Object instance using the given arguments
|
* New target Object instance using the given arguments
|
||||||
* @param constructorSupplier constructor supplier
|
* @param constructorSupplier constructor supplier
|
||||||
|
@ -80,18 +97,63 @@ public class ReflectionUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set target Object field to a certain value
|
* New target Object instance using the given Class name
|
||||||
* @param target Object whose field is being set
|
* @param className class name
|
||||||
* @param fieldName Object field naem to set
|
* @return new Object instance
|
||||||
* @param value the new value for the given field
|
|
||||||
*/
|
*/
|
||||||
public static void setField(Object target, String fieldName, Object value) {
|
public static <T> T newInstance(String className) {
|
||||||
try {
|
try {
|
||||||
Field field = getField(target.getClass(), fieldName);
|
return (T) Class.forName( className ).newInstance();
|
||||||
field.set( target, value );
|
|
||||||
}
|
}
|
||||||
catch ( IllegalAccessException e ) {
|
catch ( ClassNotFoundException | IllegalAccessException | InstantiationException e ) {
|
||||||
throw new IllegalArgumentException("Field " + fieldName + " could not be set", e );
|
throw new IllegalArgumentException("Constructor could not be called", e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get setter method
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param property property
|
||||||
|
* @param parameterType setter parameter type
|
||||||
|
* @return setter method
|
||||||
|
*/
|
||||||
|
public static Method getSetter(Object target, String property, Class<?> parameterType) {
|
||||||
|
String setterMethodName = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
|
||||||
|
Method setter = getMethod(target, setterMethodName, parameterType);
|
||||||
|
setter.setAccessible(true);
|
||||||
|
return setter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get target method
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param methodName method name
|
||||||
|
* @param parameterTypes method parameter types
|
||||||
|
* @return return value
|
||||||
|
*/
|
||||||
|
public static Method getMethod(Object target, String methodName, Class... parameterTypes) {
|
||||||
|
try {
|
||||||
|
return target.getClass().getMethod(methodName, parameterTypes);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke setter method with the given parameter
|
||||||
|
*
|
||||||
|
* @param target target object
|
||||||
|
* @param property property
|
||||||
|
* @param parameter setter parameter
|
||||||
|
*/
|
||||||
|
public static void setProperty(Object target, String property, Object parameter) {
|
||||||
|
Method setter = getSetter( target, property, parameter.getClass());
|
||||||
|
try {
|
||||||
|
setter.invoke(target, parameter);
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,22 @@ public class PreparedStatementSpyConnectionProvider
|
||||||
private final List<String> executeUpdateStatements = new ArrayList<>();
|
private final List<String> executeUpdateStatements = new ArrayList<>();
|
||||||
|
|
||||||
private final List<Connection> acquiredConnections = new ArrayList<>( );
|
private final List<Connection> acquiredConnections = new ArrayList<>( );
|
||||||
|
private final List<Connection> releasedConnections = new ArrayList<>( );
|
||||||
|
|
||||||
|
public PreparedStatementSpyConnectionProvider() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreparedStatementSpyConnectionProvider(ConnectionProvider connectionProvider) {
|
||||||
|
super( connectionProvider );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Connection actualConnection() throws SQLException {
|
||||||
|
return super.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
Connection connection = spy( super.getConnection() );
|
Connection connection = spy( actualConnection() );
|
||||||
acquiredConnections.add( connection );
|
acquiredConnections.add( connection );
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
@ -50,9 +62,16 @@ public class PreparedStatementSpyConnectionProvider
|
||||||
@Override
|
@Override
|
||||||
public void closeConnection(Connection conn) throws SQLException {
|
public void closeConnection(Connection conn) throws SQLException {
|
||||||
acquiredConnections.remove( conn );
|
acquiredConnections.remove( conn );
|
||||||
|
releasedConnections.add( conn );
|
||||||
super.closeConnection( conn );
|
super.closeConnection( conn );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
clear();
|
||||||
|
super.stop();
|
||||||
|
}
|
||||||
|
|
||||||
private Connection spy(Connection connection) {
|
private Connection spy(Connection connection) {
|
||||||
if ( MockUtil.isMock( connection ) ) {
|
if ( MockUtil.isMock( connection ) ) {
|
||||||
return connection;
|
return connection;
|
||||||
|
@ -94,6 +113,7 @@ public class PreparedStatementSpyConnectionProvider
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
acquiredConnections.clear();
|
acquiredConnections.clear();
|
||||||
|
releasedConnections.clear();
|
||||||
preparedStatementMap.keySet().forEach( Mockito::reset );
|
preparedStatementMap.keySet().forEach( Mockito::reset );
|
||||||
preparedStatementMap.clear();
|
preparedStatementMap.clear();
|
||||||
}
|
}
|
||||||
|
@ -167,4 +187,12 @@ public class PreparedStatementSpyConnectionProvider
|
||||||
public List<Connection> getAcquiredConnections() {
|
public List<Connection> getAcquiredConnections() {
|
||||||
return acquiredConnections;
|
return acquiredConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of current released Connections.
|
||||||
|
* @return list of current released Connections
|
||||||
|
*/
|
||||||
|
public List<Connection> getReleasedConnections() {
|
||||||
|
return releasedConnections;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
* 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.resource.transaction.jdbc;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
|
||||||
|
import org.hibernate.testing.jdbc.PreparedStatementSpyConnectionProvider;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vlad Mihalcea
|
||||||
|
*/
|
||||||
|
public class HikariCPSkipAutoCommitTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
private PreparedStatementSpyConnectionProvider connectionProvider =
|
||||||
|
new PreparedStatementSpyConnectionProvider();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration configuration) {
|
||||||
|
configuration.getProperties().put(
|
||||||
|
org.hibernate.cfg.AvailableSettings.CONNECTION_PROVIDER,
|
||||||
|
connectionProvider
|
||||||
|
);
|
||||||
|
configuration.getProperties().put( AvailableSettings.SKIP_AUTOCOMMIT_CHECK, Boolean.TRUE );
|
||||||
|
configuration.getProperties().put( "hibernate.hikari.autoCommit", Boolean.FALSE.toString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void releaseSessionFactory() {
|
||||||
|
super.releaseSessionFactory();
|
||||||
|
connectionProvider.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
City.class,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
connectionProvider.clear();
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
City city = new City();
|
||||||
|
city.setId( 1L );
|
||||||
|
city.setName( "Cluj-Napoca" );
|
||||||
|
session.persist( city );
|
||||||
|
|
||||||
|
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
||||||
|
assertTrue( connectionProvider.getReleasedConnections().isEmpty() );
|
||||||
|
} );
|
||||||
|
verifyConnections();
|
||||||
|
|
||||||
|
connectionProvider.clear();
|
||||||
|
doInHibernate( this::sessionFactory, session -> {
|
||||||
|
City city = session.find( City.class, 1L );
|
||||||
|
assertEquals( "Cluj-Napoca", city.getName() );
|
||||||
|
} );
|
||||||
|
verifyConnections();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyConnections() {
|
||||||
|
assertTrue( connectionProvider.getAcquiredConnections().isEmpty() );
|
||||||
|
|
||||||
|
List<Connection> connections = connectionProvider.getReleasedConnections();
|
||||||
|
assertEquals( 1, connections.size() );
|
||||||
|
Connection connection = connections.get( 0 );
|
||||||
|
try {
|
||||||
|
verify(connection, never()).setAutoCommit( false );
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
fail(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity(name = "City" )
|
||||||
|
public static class City {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#
|
||||||
|
# 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>.
|
||||||
|
#
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.Target=System.out
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||||
|
#log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L (hibernateLoadPlanWalkPath->%X{hibernateLoadPlanWalkPath}) - %m%n
|
||||||
|
|
||||||
|
#log4j.appender.stdout-mdc=org.apache.log4j.ConsoleAppender
|
||||||
|
#log4j.appender.stdout-mdc.Target=System.out
|
||||||
|
#log4j.appender.stdout-mdc.layout=org.apache.log4j.PatternLayout
|
||||||
|
#log4j.appender.stdout-mdc.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L (walk path -> %X{hibernateLoadPlanWalkPath}) - %m%n
|
||||||
|
|
||||||
|
log4j.appender.unclosedSessionFactoryFile=org.apache.log4j.FileAppender
|
||||||
|
log4j.appender.unclosedSessionFactoryFile.append=true
|
||||||
|
log4j.appender.unclosedSessionFactoryFile.file=target/tmp/log/UnclosedSessionFactoryWarnings.log
|
||||||
|
log4j.appender.unclosedSessionFactoryFile.layout=org.apache.log4j.PatternLayout
|
||||||
|
log4j.appender.unclosedSessionFactoryFile.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
|
||||||
|
|
||||||
|
log4j.rootLogger=info, stdout
|
||||||
|
|
||||||
|
#log4j.logger.org.hibernate.loader.plan=trace, stdout-mdc
|
||||||
|
#log4j.additivity.org.hibernate.loader.plan=false
|
||||||
|
#log4j.logger.org.hibernate.persister.walking=trace, stdout-mdc
|
||||||
|
#log4j.additivity.org.hibernate.persister.walking=false
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.tool.hbm2ddl=trace
|
||||||
|
log4j.logger.org.hibernate.testing.cache=debug
|
||||||
|
|
||||||
|
# SQL Logging - HHH-6833
|
||||||
|
log4j.logger.org.hibernate.SQL=debug
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.type.descriptor.sql.BasicBinder=trace
|
||||||
|
log4j.logger.org.hibernate.type.descriptor.sql.BasicExtractor=trace
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.hql.internal.ast=debug
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.sql.ordering.antlr=debug
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.loader.plan2.build.internal.LoadPlanImpl=debug
|
||||||
|
log4j.logger.org.hibernate.loader.plan2.build.spi.LoadPlanTreePrinter=debug
|
||||||
|
log4j.logger.org.hibernate.loader.plan2.exec.spi.EntityLoadQueryDetails=debug
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.engine.internal.StatisticalLoggingSessionEventListener=info
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.boot.model.source.internal.hbm.ModelBinder=debug
|
||||||
|
log4j.logger.org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry=debug
|
||||||
|
|
||||||
|
|
||||||
|
### When entity copy merge functionality is enabled using:
|
||||||
|
### hibernate.event.merge.entity_copy_observer=log, the following will
|
||||||
|
### provide information about merged entity copies.
|
||||||
|
### log4j.logger.org.hibernate.event.internal.EntityCopyAllowedLoggedObserver=debug
|
||||||
|
|
||||||
|
log4j.logger.org.hibernate.testing.junit4.TestClassMetadata=info, unclosedSessionFactoryFile
|
||||||
|
log4j.logger.org.hibernate.boot.model.process.internal.ScanningCoordinator=debug
|
|
@ -35,6 +35,13 @@ public class ConnectionProviderDelegate implements
|
||||||
|
|
||||||
private ConnectionProvider connectionProvider;
|
private ConnectionProvider connectionProvider;
|
||||||
|
|
||||||
|
public ConnectionProviderDelegate() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConnectionProviderDelegate(ConnectionProvider connectionProvider) {
|
||||||
|
this.connectionProvider = connectionProvider;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
|
@ -42,6 +49,7 @@ public class ConnectionProviderDelegate implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Map configurationValues) {
|
public void configure(Map configurationValues) {
|
||||||
|
if ( connectionProvider == null ) {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Map<String, Object> settings = new HashMap<>( configurationValues );
|
Map<String, Object> settings = new HashMap<>( configurationValues );
|
||||||
settings.remove( AvailableSettings.CONNECTION_PROVIDER );
|
settings.remove( AvailableSettings.CONNECTION_PROVIDER );
|
||||||
|
@ -54,6 +62,7 @@ public class ConnectionProviderDelegate implements
|
||||||
configurableConnectionProvider.configure( settings );
|
configurableConnectionProvider.configure( settings );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
|
|
Loading…
Reference in New Issue