HHH-10541 - Create Vibur DBCP connection pool module
This commit is contained in:
parent
794c784c0d
commit
0d9b1c54cd
|
@ -9,13 +9,14 @@ hibernate-core:: The main (core) Hibernate module. Defines its ORM features and
|
|||
hibernate-envers:: Hibernate's historical entity versioning feature
|
||||
hibernate-spatial:: Hibernate's Spatial/GIS data-type support
|
||||
hibernate-osgi:: Hibernate support for running in OSGi containers.
|
||||
hibernate-c3p0:: Integrates the link:$$http://www.mchange.com/projects/c3p0/$$[C3P0] connection pooling library into Hibernate
|
||||
hibernate-hikaricp:: Integrates the link:$$http://brettwooldridge.github.io/HikariCP/$$[HikariCP] connection pooling library into Hibernate
|
||||
hibernate-proxool:: Integrates the link:$$http://proxool.sourceforge.net/$$[Proxool] connection pooling library into Hibernate
|
||||
hibernate-jcache:: Integrates the link:$$https://jcp.org/en/jsr/detail?id=107$$[JCache] caching specification into Hibernate,
|
||||
hibernate-c3p0:: Integrates the http://www.mchange.com/projects/c3p0/[C3P0] connection pooling library into Hibernate
|
||||
hibernate-hikaricp:: Integrates the http://brettwooldridge.github.io/HikariCP/[HikariCP] connection pooling library into Hibernate
|
||||
hibernate-vibur:: Integrates the http://www.vibur.org/[Vibur DBCP] connection pooling library into Hibernate
|
||||
hibernate-proxool:: Integrates the http://proxool.sourceforge.net/[Proxool] connection pooling library into Hibernate
|
||||
hibernate-jcache:: Integrates the https://jcp.org/en/jsr/detail?id=107$$[JCache] caching specification into Hibernate,
|
||||
enabling any compliant implementation to become a second-level cache provider.
|
||||
hibernate-ehcache:: Integrates the link:$$http://ehcache.org/$$[Ehcache] caching library into Hibernate as a second-level cache provider.
|
||||
hibernate-infinispan:: Integrates the link:$$http://infinispan.org/$$[Infinispan] caching library into Hibernate as a second-level cache provider.
|
||||
hibernate-ehcache:: Integrates the http://ehcache.org/[Ehcache] caching library into Hibernate as a second-level cache provider.
|
||||
hibernate-infinispan:: Integrates the http://infinispan.org/[Infinispan] caching library into Hibernate as a second-level cache provider.
|
||||
|
||||
|
||||
=== Release Bundle Downloads
|
||||
|
|
|
@ -18,8 +18,9 @@ Hibernate will internally determine which `ConnectionProvider` to use based on t
|
|||
3. else if any setting prefixed by `hibernate.c3p0.` is set -> <<database-connectionprovider-c3p0>>
|
||||
4. else if any setting prefixed by `hibernate.proxool.` is set -> <<database-connectionprovider-proxool>>
|
||||
5. else if any setting prefixed by `hibernate.hikari.` is set -> <<database-connectionprovider-hikari>>
|
||||
6. else if `hibernate.connection.url` is set -> <<database-connectionprovider-drivermanager>>
|
||||
7. else -> <<database-connectionprovider-provided>>
|
||||
6. else if any setting prefixed by `hibernate.vibur.` is set -> <<database-connectionprovider-vibur>>
|
||||
7. else if `hibernate.connection.url` is set -> <<database-connectionprovider-drivermanager>>
|
||||
8. else -> <<database-connectionprovider-provided>>
|
||||
|
||||
[[database-connectionprovider-datasource]]
|
||||
=== Using DataSources
|
||||
|
@ -96,7 +97,7 @@ See http://proxool.sourceforge.net/configure.html[proxool configuration].
|
|||
`hibernate.proxool.pool_alias` must be set to indicate which pool to use.
|
||||
|
||||
[[database-connectionprovider-hikari]]
|
||||
=== Using Hikari
|
||||
=== Using HikariCP
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
|
@ -116,6 +117,26 @@ Additionally, this `ConnectionProvider` will pick up the following Hibernate-spe
|
|||
Note that Hikari only supports JDBC standard isolation levels (apparently).
|
||||
`hibernate.connection.autocommit`:: Mapped to Hikari's `autoCommit` setting
|
||||
|
||||
[[database-connectionprovider-vibur]]
|
||||
=== Using Vibur DBCP
|
||||
|
||||
[IMPORTANT]
|
||||
====
|
||||
To use this integration, the application must include the hibernate-vibur module jar (as well as its dependencies) on the classpath.
|
||||
====
|
||||
|
||||
Hibernate also provides support for applications to use http://www.vibur.org/[Vibur DBCP] connection pool.
|
||||
|
||||
Set all of your Vibur settings in Hibernate prefixed by `hibernate.vibur.` and this `ConnectionProvider` will pick them up and pass them along to Vibur DBCP.
|
||||
Additionally, this `ConnectionProvider` will pick up the following Hibernate-specific properties and map them to the corresponding Vibur ones (any `hibernate.vibur.` prefixed ones have precedence):
|
||||
|
||||
`hibernate.connection.driver_class`:: Mapped to Vibur's `driverClassName` setting
|
||||
`hibernate.connection.url`:: Mapped to Vibur's `jdbcUrl` setting
|
||||
`hibernate.connection.username`:: Mapped to Vibur's `username` setting
|
||||
`hibernate.connection.password`:: Mapped to Vibur's `password` setting
|
||||
`hibernate.connection.isolation`:: Mapped to Vibur's `defaultTransactionIsolationValue` setting. See <<ConnectionProvider support for transaction isolation setting>>.
|
||||
`hibernate.connection.autocommit`:: Mapped to Vibur's `defaultAutoCommit` setting
|
||||
|
||||
[[database-connectionprovider-drivermanager]]
|
||||
=== Using Hibernate's built-in (and unsupported) pooling
|
||||
|
||||
|
|
|
@ -56,10 +56,15 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
|
|||
public static final String PROXOOL_STRATEGY = "proxool";
|
||||
|
||||
/**
|
||||
* The strategy for proxool connection pooling
|
||||
* The strategy for hikari connection pooling
|
||||
*/
|
||||
public static final String HIKARI_STRATEGY = "hikari";
|
||||
|
||||
/**
|
||||
* The strategy for vibur connection pooling
|
||||
*/
|
||||
public static final String VIBUR_STRATEGY = "vibur";
|
||||
|
||||
/**
|
||||
* No idea. Is this even still used?
|
||||
*/
|
||||
|
@ -154,6 +159,12 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
|
|||
}
|
||||
}
|
||||
|
||||
if ( connectionProvider == null ) {
|
||||
if ( viburConfigDefined( configurationValues ) ) {
|
||||
connectionProvider = instantiateViburProvider( strategySelector );
|
||||
}
|
||||
}
|
||||
|
||||
if ( connectionProvider == null ) {
|
||||
if ( configurationValues.get( AvailableSettings.URL ) != null ) {
|
||||
connectionProvider = new DriverManagerConnectionProviderImpl();
|
||||
|
@ -264,6 +275,29 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
|
|||
}
|
||||
}
|
||||
|
||||
private boolean viburConfigDefined(Map configValues) {
|
||||
for ( Object key : configValues.keySet() ) {
|
||||
if ( !String.class.isInstance( key ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ( (String) key ).startsWith( "hibernate.vibur." ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private ConnectionProvider instantiateViburProvider(StrategySelector strategySelector) {
|
||||
try {
|
||||
return strategySelector.selectStrategyImplementor( ConnectionProvider.class, VIBUR_STRATEGY ).newInstance();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.viburProviderClassNotFound();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the connection properties capable of being passed to the {@link java.sql.DriverManager#getConnection}
|
||||
* forms taking {@link Properties} argument. We seek out all keys in the passed map which start with
|
||||
|
|
|
@ -1782,4 +1782,9 @@ public interface CoreMessageLogger extends BasicLogger {
|
|||
"issue HHH-11936 for details."
|
||||
)
|
||||
void emptyCompositesEnabled();
|
||||
|
||||
@LogMessage(level = WARN)
|
||||
@Message(value = "Vibur properties were encountered, but the Vibur ConnectionProvider was not found on the classpath; these properties are going to be ignored.",
|
||||
id = 484)
|
||||
void viburProviderClassNotFound();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
dependencies {
|
||||
compile project( ':hibernate-core' )
|
||||
compile( libraries.vibur )
|
||||
testCompile( group: 'org.vibur', name: 'vibur-dbcp', version: '21.2', classifier: 'tests' )
|
||||
testCompile( group: 'com.googlecode.concurrentlinkedhashmap', name: 'concurrentlinkedhashmap-lru', version: '1.4.2' )
|
||||
testCompile project( ':hibernate-testing' )
|
||||
testCompile( libraries.mockito )
|
||||
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Java 9 ftw!
|
||||
if ( JavaVersion.current().isJava9Compatible() ) {
|
||||
// The JDK used to run Gradle is Java 9+, and we assume that that is the same
|
||||
// JDK for executing tasks
|
||||
compile( 'com.sun.xml.bind:jaxb-impl:2.2.11' )
|
||||
compile( 'org.glassfish.jaxb:jaxb-xjc:2.2.11' )
|
||||
compile( 'org.jvnet.jaxb2_commons:jaxb2-basics:0.11.0' )
|
||||
compile( 'org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.11.0' )
|
||||
compile( 'javax:javaee-api:7.0' )
|
||||
|
||||
testCompile( 'com.sun.xml.bind:jaxb-impl:2.2.11' )
|
||||
testCompile( 'org.glassfish.jaxb:jaxb-xjc:2.2.11' )
|
||||
testCompile( 'org.jvnet.jaxb2_commons:jaxb2-basics:0.11.0' )
|
||||
testCompile( 'org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.11.0' )
|
||||
testCompile( 'javax:javaee-api:7.0' )
|
||||
|
||||
testRuntime( 'com.sun.xml.bind:jaxb-impl:2.2.11' )
|
||||
testRuntime( 'org.glassfish.jaxb:jaxb-xjc:2.2.11' )
|
||||
testRuntime( 'org.jvnet.jaxb2_commons:jaxb2-basics:0.11.0' )
|
||||
testRuntime( 'org.jvnet.jaxb2_commons:jaxb2-basics-ant:0.11.0' )
|
||||
testRuntime( 'javax:javaee-api:7.0' )
|
||||
}
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
}
|
||||
|
||||
mavenPom {
|
||||
name = 'Hibernate/ViburDBCP Integration'
|
||||
description = 'Integration for ViburDBCP into Hibernate O/RM'
|
||||
}
|
||||
|
||||
def osgiDescription() {
|
||||
return mavenPom.description
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.vibur.internal;
|
||||
|
||||
import org.hibernate.boot.registry.selector.SimpleStrategyRegistrationImpl;
|
||||
import org.hibernate.boot.registry.selector.StrategyRegistration;
|
||||
import org.hibernate.boot.registry.selector.StrategyRegistrationProvider;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides the {@link ViburDBCPConnectionProvider} to the
|
||||
* {@link org.hibernate.boot.registry.selector.spi.StrategySelector} service.
|
||||
*
|
||||
* @author Simeon Malchev
|
||||
*/
|
||||
public class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
|
||||
private static final List<StrategyRegistration> REGISTRATIONS = Collections.singletonList(
|
||||
(StrategyRegistration) new SimpleStrategyRegistrationImpl<>(
|
||||
ConnectionProvider.class,
|
||||
ViburDBCPConnectionProvider.class,
|
||||
"vibur",
|
||||
"viburdbcp",
|
||||
ViburDBCPConnectionProvider.class.getSimpleName(),
|
||||
// for backward compatibility with pre-existing Vibur project Hibernate integration artifacts
|
||||
"org.vibur.dbcp.integration.ViburDBCPConnectionProvider",
|
||||
// for consistency's sake
|
||||
"org.hibernate.connection.ViburDBCPConnectionProvider"
|
||||
)
|
||||
);
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterable<StrategyRegistration> getStrategyRegistrations() {
|
||||
return REGISTRATIONS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* 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.vibur.internal;
|
||||
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.service.UnknownUnwrapTypeException;
|
||||
import org.hibernate.service.spi.Configurable;
|
||||
import org.hibernate.service.spi.Stoppable;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.*;
|
||||
|
||||
/**
|
||||
* <p>ViburDBCP connection provider for Hibernate integration.
|
||||
*
|
||||
* To use this connection provider set:
|
||||
* <pre>
|
||||
* hibernate.connection.provider_class ViburDBCPConnectionProvider
|
||||
* </pre>
|
||||
*
|
||||
* Supported Hibernate properties are:
|
||||
* <pre>
|
||||
* hibernate.connection.driver_class
|
||||
* hibernate.connection.url
|
||||
* hibernate.connection.username
|
||||
* hibernate.connection.password
|
||||
* hibernate.connection.isolation
|
||||
* hibernate.connection.autocommit
|
||||
* </pre>
|
||||
*
|
||||
* All {@link org.vibur.dbcp.ViburConfig} properties are also supported via using the
|
||||
* {@code hibernate.vibur} prefix.
|
||||
*
|
||||
* @see ConnectionProvider
|
||||
*
|
||||
* @author Simeon Malchev
|
||||
*/
|
||||
public class ViburDBCPConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
|
||||
|
||||
private static final String VIBUR_PREFIX = "hibernate.vibur.";
|
||||
|
||||
private ViburDBCPDataSource dataSource = null;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void configure(Map configurationValues) {
|
||||
dataSource = new ViburDBCPDataSource(transform(configurationValues));
|
||||
dataSource.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Connection getConnection() throws SQLException {
|
||||
return dataSource.getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection(Connection conn) throws SQLException {
|
||||
conn.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (dataSource != null) {
|
||||
dataSource.terminate();
|
||||
dataSource = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAggressiveRelease() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrappableAs(Class unwrapType) {
|
||||
return ConnectionProvider.class.equals(unwrapType) ||
|
||||
ViburDBCPConnectionProvider.class.isAssignableFrom(unwrapType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public <T> T unwrap(Class<T> unwrapType) {
|
||||
if (isUnwrappableAs(unwrapType)) {
|
||||
return (T) this;
|
||||
}
|
||||
else {
|
||||
throw new UnknownUnwrapTypeException(unwrapType);
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties transform(Map<String, String> configurationValues) {
|
||||
Properties result = new Properties();
|
||||
|
||||
String driverClassName = configurationValues.get(DRIVER);
|
||||
if (driverClassName != null) {
|
||||
result.setProperty("driverClassName", driverClassName);
|
||||
}
|
||||
String jdbcUrl = configurationValues.get(URL);
|
||||
if (jdbcUrl != null) {
|
||||
result.setProperty("jdbcUrl", jdbcUrl);
|
||||
}
|
||||
|
||||
String username = configurationValues.get(USER);
|
||||
if (username != null) {
|
||||
result.setProperty("username", username);
|
||||
}
|
||||
String password = configurationValues.get(PASS);
|
||||
if (password != null) {
|
||||
result.setProperty("password", password);
|
||||
}
|
||||
|
||||
String defaultTransactionIsolationValue = configurationValues.get(ISOLATION);
|
||||
if (defaultTransactionIsolationValue != null) {
|
||||
result.setProperty("defaultTransactionIsolationValue", defaultTransactionIsolationValue);
|
||||
}
|
||||
String defaultAutoCommit = configurationValues.get(AUTOCOMMIT);
|
||||
if (defaultAutoCommit != null) {
|
||||
result.setProperty("defaultAutoCommit", defaultAutoCommit);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : configurationValues.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith(VIBUR_PREFIX)) {
|
||||
key = key.substring(VIBUR_PREFIX.length());
|
||||
result.setProperty(key, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Visible for testing purposes.
|
||||
*/
|
||||
public ViburDBCPDataSource getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of ConnectionProvider using ViburDBCP.
|
||||
*/
|
||||
package org.hibernate.vibur.internal;
|
|
@ -0,0 +1,13 @@
|
|||
#
|
||||
# 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>.
|
||||
#
|
||||
#
|
||||
# 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>.
|
||||
#
|
||||
org.hibernate.vibur.internal.StrategyRegistrationProviderImpl
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ 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>.
|
||||
-->
|
||||
<blueprint default-activation="eager"
|
||||
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
|
||||
>
|
||||
|
||||
<bean id="strategyRegistrationProvider" class="org.hibernate.vibur.internal.StrategyRegistrationProviderImpl"/>
|
||||
<service ref="strategyRegistrationProvider" interface="org.hibernate.boot.registry.selector.StrategyRegistrationProvider"/>
|
||||
|
||||
</blueprint>
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* 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.vibur;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.hibernate.vibur.internal.ViburDBCPConnectionProvider;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||
import org.vibur.dbcp.stcache.StatementHolder;
|
||||
import org.vibur.dbcp.stcache.StatementMethod;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import static org.hibernate.cfg.AvailableSettings.*;
|
||||
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.same;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.vibur.dbcp.AbstractDataSourceTest.mockStatementCache;
|
||||
import static org.vibur.dbcp.stcache.StatementHolder.State.AVAILABLE;
|
||||
|
||||
/**
|
||||
* Hibernate unit/integration test for {@link ViburDBCPConnectionProvider}.
|
||||
*
|
||||
* @author Simeon Malchev
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ViburDBCPConnectionProviderTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
private int poolMaxSize;
|
||||
private int statementCacheMaxSize;
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
Properties properties = configuration.getProperties();
|
||||
properties.put(CONNECTION_PROVIDER, ViburDBCPConnectionProvider.class);
|
||||
properties.put(SHOW_SQL, Boolean.TRUE);
|
||||
properties.put(FORMAT_SQL, Boolean.TRUE);
|
||||
|
||||
properties.put("hibernate.vibur.poolInitialSize", "1");
|
||||
properties.put("hibernate.vibur.poolMaxSize", Integer.toString(poolMaxSize));
|
||||
properties.put("hibernate.vibur.logQueryExecutionLongerThanMs", "100");
|
||||
properties.put("hibernate.vibur.statementCacheMaxSize", Integer.toString(statementCacheMaxSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] { Actor.class };
|
||||
}
|
||||
|
||||
public void setUpPoolAndDatabase(int poolMaxSize, int statementCacheMaxSize) {
|
||||
this.poolMaxSize = poolMaxSize;
|
||||
this.statementCacheMaxSize = statementCacheMaxSize;
|
||||
buildSessionFactory();
|
||||
|
||||
doInHibernate(this::sessionFactory, session -> {
|
||||
addDbRecord(session, "CHRISTIAN", "GABLE");
|
||||
addDbRecord(session, "CHRISTIAN", "AKROYD");
|
||||
addDbRecord(session, "CHRISTIAN", "NEESON");
|
||||
addDbRecord(session, "CAMERON", "NEESON");
|
||||
addDbRecord(session, "RAY", "JOHANSSON");
|
||||
});
|
||||
}
|
||||
|
||||
private static void addDbRecord(Session session, String firstName, String lastName) {
|
||||
Actor actor = new Actor();
|
||||
actor.setFirstName(firstName);
|
||||
actor.setLastName(lastName);
|
||||
session.persist(actor);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
releaseSessionFactory();
|
||||
}
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<StatementMethod> key1, key2;
|
||||
@Captor
|
||||
private ArgumentCaptor<StatementHolder> val1;
|
||||
|
||||
@Test
|
||||
public void testSelectStatementNoStatementsCache() {
|
||||
setUpPoolAndDatabase(2, 0 /* disables the statements cache */ );
|
||||
|
||||
doInHibernate(this::sessionFactory, ViburDBCPConnectionProviderTest::executeAndVerifySelect);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSelectStatementWithStatementsCache() {
|
||||
setUpPoolAndDatabase(1, 10 /* statement cache is enabled */ );
|
||||
|
||||
ConnectionProvider cp = sessionFactory().getServiceRegistry().getService(ConnectionProvider.class);
|
||||
ViburDBCPDataSource ds = ((ViburDBCPConnectionProvider) cp).getDataSource();
|
||||
|
||||
ConcurrentMap<StatementMethod, StatementHolder> mockedStatementCache = mockStatementCache(ds);
|
||||
|
||||
doInHibernate(this::sessionFactory, ViburDBCPConnectionProviderTest::executeAndVerifySelect);
|
||||
|
||||
// We set above the poolMaxSize = 1, that's why the second session will get and use the same underlying connection.
|
||||
doInHibernate(this::sessionFactory, ViburDBCPConnectionProviderTest::executeAndVerifySelect);
|
||||
|
||||
InOrder inOrder = inOrder(mockedStatementCache);
|
||||
inOrder.verify(mockedStatementCache).get(key1.capture());
|
||||
inOrder.verify(mockedStatementCache).putIfAbsent(same(key1.getValue()), val1.capture());
|
||||
inOrder.verify(mockedStatementCache).get(key2.capture());
|
||||
|
||||
assertEquals(1, mockedStatementCache.size());
|
||||
assertTrue(mockedStatementCache.containsKey(key1.getValue()));
|
||||
assertEquals(key1.getValue(), key2.getValue());
|
||||
assertEquals(AVAILABLE, val1.getValue().state().get());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void executeAndVerifySelect(Session session) {
|
||||
List<Actor> list = session.createQuery("from Actor where firstName = ?0")
|
||||
.setParameter(0, "CHRISTIAN").list();
|
||||
|
||||
Set<String> expectedLastNames = new HashSet<>(Arrays.asList("GABLE", "AKROYD", "NEESON"));
|
||||
assertEquals(expectedLastNames.size(), list.size());
|
||||
for (Actor actor : list) {
|
||||
assertTrue(expectedLastNames.remove(actor.getLastName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name="Actor")
|
||||
public static class Actor {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#
|
||||
# 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>.
|
||||
#
|
||||
hibernate.dialect @db.dialect@
|
||||
hibernate.connection.driver_class @jdbc.driver@
|
||||
hibernate.connection.url @jdbc.url@
|
||||
hibernate.connection.username @jdbc.user@
|
||||
hibernate.connection.password @jdbc.pass@
|
||||
|
||||
hibernate.jdbc.batch_size 10
|
||||
hibernate.connection.provider_class ViburDBCPConnectionProvider
|
|
@ -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
|
|
@ -132,6 +132,7 @@ ext {
|
|||
jcache: "javax.cache:cache-api:1.0.0",
|
||||
proxool: "proxool:proxool:0.8.3",
|
||||
hikaricp: "com.zaxxer:HikariCP:2.5.1",
|
||||
vibur: "org.vibur:vibur-dbcp:21.2",
|
||||
|
||||
cdi: "javax.enterprise:cdi-api:${cdiVersion}",
|
||||
weld: "org.jboss.weld.se:weld-se-shaded:${weldVersion}",
|
||||
|
|
|
@ -21,6 +21,7 @@ include 'hibernate-osgi'
|
|||
include 'hibernate-c3p0'
|
||||
include 'hibernate-proxool'
|
||||
include 'hibernate-hikaricp'
|
||||
include 'hibernate-vibur'
|
||||
|
||||
include 'hibernate-jcache'
|
||||
include 'hibernate-ehcache'
|
||||
|
|
Loading…
Reference in New Issue