diff --git a/documentation/src/main/asciidoc/introduction/Configuration.adoc b/documentation/src/main/asciidoc/introduction/Configuration.adoc
index 5056c7c6d204..ddac4a3dc61c 100644
--- a/documentation/src/main/asciidoc/introduction/Configuration.adoc
+++ b/documentation/src/main/asciidoc/introduction/Configuration.adoc
@@ -355,9 +355,11 @@ You can set the size of Hibernate's built-in connection pool using this property
|===
| Configuration property name | Purpose
-| `hibernate.connection.pool_size` | The size of the built-in connection pool
+| `hibernate.connection.pool_size` | The size of the connection pool
|===
+This configuration property is also respected when you use Agroal, HikariCP, or c3p0 for connection pooling.
+
[CAUTION]
// .The default connection pool is not meant for production use
====
diff --git a/documentation/src/main/asciidoc/introduction/Tuning.adoc b/documentation/src/main/asciidoc/introduction/Tuning.adoc
index 13e44cd5d974..8c6d3a3f2ebb 100644
--- a/documentation/src/main/asciidoc/introduction/Tuning.adoc
+++ b/documentation/src/main/asciidoc/introduction/Tuning.adoc
@@ -72,6 +72,7 @@ The following settings are common to all connection pools supported by Hibernate
.Common settings for connection pools
[%breakable,cols="37,~"]
|===
+| link:{doc-javadoc-url}/org/hibernate/cfg/JdbcSettings.html#POOL_SIZE[`hibernate.connection.pool_size`] | The size of the connection pool
| link:{doc-javadoc-url}/org/hibernate/cfg/JdbcSettings.html#AUTOCOMMIT[`hibernate.connection.autocommit`] | The default autocommit mode
| link:{doc-javadoc-url}/org/hibernate/cfg/JdbcSettings.html#ISOLATION[`hibernate.connection.isolation`] | The default transaction isolation level
|===
diff --git a/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/AgroalConnectionProvider.java b/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/AgroalConnectionProvider.java
index 092eaa8d7758..40fdf741d2ce 100644
--- a/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/AgroalConnectionProvider.java
+++ b/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/AgroalConnectionProvider.java
@@ -4,21 +4,24 @@
*/
package org.hibernate.agroal.internal;
+import java.io.Serial;
import java.sql.Connection;
import java.sql.SQLException;
-import java.sql.DatabaseMetaData;
import javax.sql.DataSource;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
+import io.agroal.api.configuration.AgroalConnectionFactoryConfiguration.TransactionIsolation;
import org.hibernate.HibernateException;
import org.hibernate.cfg.AgroalSettings;
import org.hibernate.cfg.AvailableSettings;
+import org.hibernate.cfg.JdbcSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.service.UnknownUnwrapTypeException;
@@ -33,14 +36,19 @@
import io.agroal.api.security.NamePrincipal;
import io.agroal.api.security.SimplePassword;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toMap;
import static org.hibernate.cfg.AgroalSettings.AGROAL_CONFIG_PREFIX;
import static org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.allowJdbcMetadataAccess;
/**
- * ConnectionProvider based on Agroal connection pool
- * To use this ConnectionProvider set:
hibernate.connection.provider_class AgroalConnectionProvider
- *
- * Usual hibernate properties are supported:
+ * {@link ConnectionProvider} based on Agroal connection pool.
+ *
+ * To force the use of this {@code ConnectionProvider} set
+ * {@value org.hibernate.cfg.JdbcSettings#CONNECTION_PROVIDER}
+ * to {@code agroal}.
+ *
+ * Usual hibernate connection properties are supported:
*
* hibernate.connection.driver_class
* hibernate.connection.url
@@ -49,8 +57,8 @@
* hibernate.connection.autocommit
* hibernate.connection.isolation
*
- *
- * Other configuration options are available, using the {@code hibernate.agroal} prefix
+ *
+ * Other configuration options are available, using the {@code hibernate.agroal} prefix.
*
* @see AgroalSettings
* @see AgroalPropertiesReader
@@ -61,6 +69,8 @@
public class AgroalConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
public static final String CONFIG_PREFIX = AGROAL_CONFIG_PREFIX + ".";
+
+ @Serial
private static final long serialVersionUID = 1L;
private AgroalDataSource agroalDataSource = null;
private boolean isMetadataAccessAllowed = true;
@@ -68,43 +78,52 @@ public class AgroalConnectionProvider implements ConnectionProvider, Configurabl
// --- Configurable
private static String extractIsolationAsString(Map properties) {
- Integer isolation = ConnectionProviderInitiator.extractIsolation( properties );
- if ( isolation != null ) {
- // Agroal resolves transaction isolation from the 'nice' name
- return ConnectionProviderInitiator.toIsolationNiceName( isolation );
- }
- return null;
+ final Integer isolation = ConnectionProviderInitiator.extractIsolation( properties );
+ return isolation != null ?
+ // Agroal resolves transaction isolation from the 'nice' name
+ ConnectionProviderInitiator.toIsolationNiceName( isolation )
+ : null;
}
private static void resolveIsolationSetting(Map properties, AgroalConnectionFactoryConfigurationSupplier cf) {
- String isolationString = extractIsolationAsString( properties );
+ final String isolationString = extractIsolationAsString( properties );
if ( isolationString != null ) {
- cf.jdbcTransactionIsolation( AgroalConnectionFactoryConfiguration.TransactionIsolation.valueOf( isolationString ) );
+ cf.jdbcTransactionIsolation( TransactionIsolation.valueOf( isolationString ) );
}
}
private static void copyProperty(Map properties, String key, Consumer consumer, Function converter) {
- Object value = properties.get( key );
- if ( value instanceof String ) {
- consumer.accept( converter.apply( (String) value ) );
+ final Object value = properties.get( key );
+ if ( value != null ) {
+ consumer.accept( converter.apply( value.toString() ) );
}
}
@Override
- public void configure(Map props) throws HibernateException {
- isMetadataAccessAllowed = allowJdbcMetadataAccess( props );
+ public void configure(Map properties) throws HibernateException {
+ isMetadataAccessAllowed = allowJdbcMetadataAccess( properties );
ConnectionInfoLogger.INSTANCE.configureConnectionPool( "Agroal" );
try {
- AgroalPropertiesReader agroalProperties = new AgroalPropertiesReader( CONFIG_PREFIX )
- .readProperties( (Map) props ); //TODO: this is a garbage cast
- agroalProperties.modify().connectionPoolConfiguration( cp -> cp.connectionFactoryConfiguration( cf -> {
- copyProperty( props, AvailableSettings.DRIVER, cf::connectionProviderClassName, Function.identity() );
- copyProperty( props, AvailableSettings.URL, cf::jdbcUrl, Function.identity() );
- copyProperty( props, AvailableSettings.USER, cf::principal, NamePrincipal::new );
- copyProperty( props, AvailableSettings.PASS, cf::credential, SimplePassword::new );
- copyProperty( props, AvailableSettings.AUTOCOMMIT, cf::autoCommit, Boolean::valueOf );
- resolveIsolationSetting( props, cf );
+ final Map config = toStringValuedProperties( properties );
+ if ( !properties.containsKey( AgroalSettings.AGROAL_MAX_SIZE ) ) {
+ final String maxSize =
+ properties.containsKey( JdbcSettings.POOL_SIZE )
+ ? properties.get( JdbcSettings.POOL_SIZE ).toString()
+ : String.valueOf( 10 );
+ config.put( AgroalSettings.AGROAL_MAX_SIZE, maxSize );
+ }
+ final AgroalPropertiesReader agroalProperties =
+ new AgroalPropertiesReader( CONFIG_PREFIX )
+ .readProperties( config );
+ agroalProperties.modify()
+ .connectionPoolConfiguration( cp -> cp.connectionFactoryConfiguration( cf -> {
+ copyProperty( properties, JdbcSettings.DRIVER, cf::connectionProviderClassName, identity() );
+ copyProperty( properties, JdbcSettings.URL, cf::jdbcUrl, identity() );
+ copyProperty( properties, JdbcSettings.USER, cf::principal, NamePrincipal::new );
+ copyProperty( properties, JdbcSettings.PASS, cf::credential, SimplePassword::new );
+ copyProperty( properties, JdbcSettings.AUTOCOMMIT, cf::autoCommit, Boolean::valueOf );
+ resolveIsolationSetting( properties, cf );
return cf;
} ) );
@@ -112,10 +131,16 @@ public void configure(Map props) throws HibernateException {
}
catch ( Exception e ) {
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
- throw new HibernateException( e );
+ throw new ConnectionProviderConfigurationException(
+ "Could not configure Agroal: " + e.getMessage(), e );
}
}
+ private static Map toStringValuedProperties(Map properties) {
+ return properties.entrySet().stream()
+ .collect( toMap( Map.Entry::getKey, e -> e.getValue().toString() ) );
+ }
+
// --- ConnectionProvider
@Override
@@ -138,30 +163,31 @@ public boolean supportsAggressiveRelease() {
@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
- final AgroalConnectionPoolConfiguration acpc = agroalDataSource.getConfiguration().connectionPoolConfiguration();
+ final AgroalConnectionPoolConfiguration acpc =
+ agroalDataSource.getConfiguration().connectionPoolConfiguration();
final AgroalConnectionFactoryConfiguration acfc = acpc.connectionFactoryConfiguration();
-
-
return new DatabaseConnectionInfoImpl(
acfc.jdbcUrl(),
- // Attempt to resolve the driver name from the dialect, in case it wasn't explicitly set and access to
- // the database metadata is allowed
- acfc.connectionProviderClass() != null ? acfc.connectionProviderClass().toString() : extractDriverNameFromMetadata(),
+ // Attempt to resolve the driver name from the dialect,
+ // in case it wasn't explicitly set and access to the
+ // database metadata is allowed
+ acfc.connectionProviderClass() != null
+ ? acfc.connectionProviderClass().toString()
+ : extractDriverNameFromMetadata(),
dialect.getVersion(),
Boolean.toString( acfc.autoCommit() ),
acfc.jdbcTransactionIsolation() != null
? ConnectionProviderInitiator.toIsolationNiceName( acfc.jdbcTransactionIsolation().level() )
: null,
acpc.minSize(),
- acpc.minSize()
+ acpc.maxSize()
);
}
private String extractDriverNameFromMetadata() {
if (isMetadataAccessAllowed) {
try ( Connection conn = getConnection() ) {
- DatabaseMetaData dbmd = conn.getMetaData();
- return dbmd.getDriverName();
+ return conn.getMetaData().getDriverName();
}
catch (SQLException e) {
// Do nothing
@@ -195,8 +221,11 @@ public T unwrap(Class unwrapType) {
@Override
public void stop() {
if ( agroalDataSource != null ) {
- ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( agroalDataSource.getConfiguration().connectionPoolConfiguration().
- connectionFactoryConfiguration().jdbcUrl() );
+ ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool(
+ agroalDataSource.getConfiguration()
+ .connectionPoolConfiguration()
+ .connectionFactoryConfiguration()
+ .jdbcUrl() );
agroalDataSource.close();
}
}
diff --git a/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/package-info.java b/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/package-info.java
index 8ac3c9e6943a..dcd7eb663070 100644
--- a/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/package-info.java
+++ b/hibernate-agroal/src/main/java/org/hibernate/agroal/internal/package-info.java
@@ -6,6 +6,6 @@
*/
/**
- * Implementation of ConnectionProvider using Agroal.
+ * Implementation of {@code ConnectionProvider} using Agroal.
*/
package org.hibernate.agroal.internal;
diff --git a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java
index 27408fa059f2..a47a80ad4a9f 100644
--- a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java
+++ b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java
@@ -4,49 +4,66 @@
*/
package org.hibernate.c3p0.internal;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.function.Function;
-import javax.sql.DataSource;
-
import com.mchange.v2.c3p0.DataSources;
-
-import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
-import org.hibernate.cfg.C3p0Settings;
import org.hibernate.cfg.JdbcSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.log.ConnectionInfoLogger;
-import org.hibernate.internal.util.PropertiesHelper;
import org.hibernate.service.UnknownUnwrapTypeException;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.Stoppable;
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.function.Function;
+
+import static com.mchange.v2.c3p0.DataSources.pooledDataSource;
+import static com.mchange.v2.c3p0.DataSources.unpooledDataSource;
+import static java.util.Objects.requireNonNullElse;
import static org.hibernate.c3p0.internal.C3P0MessageLogger.C3P0_MSG_LOGGER;
+import static org.hibernate.cfg.C3p0Settings.C3P0_ACQUIRE_INCREMENT;
+import static org.hibernate.cfg.C3p0Settings.C3P0_CONFIG_PREFIX;
+import static org.hibernate.cfg.C3p0Settings.C3P0_IDLE_TEST_PERIOD;
+import static org.hibernate.cfg.C3p0Settings.C3P0_MAX_SIZE;
+import static org.hibernate.cfg.C3p0Settings.C3P0_MAX_STATEMENTS;
+import static org.hibernate.cfg.C3p0Settings.C3P0_MIN_SIZE;
+import static org.hibernate.cfg.C3p0Settings.C3P0_TIMEOUT;
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.extractSetting;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
import static org.hibernate.internal.util.config.ConfigurationHelper.getInteger;
/**
- * A connection provider that uses a C3P0 connection pool. Hibernate will use this by
- * default if the {@code hibernate.c3p0.*} properties are set.
+ * {@link ConnectionProvider} based on c3p0 connection pool.
+ *
+ * To force the use of this {@code ConnectionProvider} set
+ * {@value org.hibernate.cfg.JdbcSettings#CONNECTION_PROVIDER}
+ * to {@code c3p0}.
+ *
+ * Hibernate selects this by default if the {@code hibernate.c3p0.*} properties are set.
*
* @author various people
* @see ConnectionProvider
*/
public class C3P0ConnectionProvider
implements ConnectionProvider, Configurable, Stoppable, ServiceRegistryAwareService {
- private static volatile String HIBERNATE_STYLE_SETTING_PREFIX = C3p0Settings.C3P0_CONFIG_PREFIX + ".";
+
+ // as specified by c3p0 documentation:
+ public static final int DEFAULT_MIN_POOL_SIZE = 3;
+ public static final int DEFAULT_MAX_POOL_SIZE = 15;
+
+ private static final String HIBERNATE_STYLE_SETTING_PREFIX = C3P0_CONFIG_PREFIX + ".";
//swaldman 2006-08-28: define c3p0-style configuration parameters for properties with
// hibernate-specific overrides to detect and warn about conflicting
@@ -62,7 +79,7 @@ public class C3P0ConnectionProvider
// hibernate sensibly lets default to minPoolSize, but we'll let users
// override it with the c3p0-style property if they want.
private static final String C3P0_STYLE_INITIAL_POOL_SIZE = "c3p0.initialPoolSize";
- private DataSource ds;
+ private DataSource dataSource;
private Integer isolation;
private boolean autocommit;
@@ -71,7 +88,7 @@ public class C3P0ConnectionProvider
@Override
public Connection getConnection() throws SQLException {
- final Connection connection = ds.getConnection();
+ final Connection connection = dataSource.getConnection();
if ( isolation != null && isolation != connection.getTransactionIsolation() ) {
connection.setTransactionIsolation( isolation );
}
@@ -101,7 +118,7 @@ public T unwrap(Class unwrapType) {
return (T) this;
}
else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
- return (T) ds;
+ return (T) dataSource;
}
else {
throw new UnknownUnwrapTypeException( unwrapType );
@@ -109,26 +126,56 @@ else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
}
@Override
- public void configure(Map props) {
- ConnectionInfoLogger.INSTANCE.configureConnectionPool( "C3p0" );
+ public void configure(Map properties) {
+ ConnectionInfoLogger.INSTANCE.configureConnectionPool( "c3p0" );
final String jdbcDriverClass = extractSetting(
- props,
+ properties,
JdbcSettings.JAKARTA_JDBC_DRIVER,
JdbcSettings.DRIVER,
JdbcSettings.JPA_JDBC_DRIVER
);
final String jdbcUrl = extractSetting(
- props,
+ properties,
JdbcSettings.JAKARTA_JDBC_URL,
JdbcSettings.URL,
JdbcSettings.JPA_JDBC_URL
);
- final Properties connectionProps = ConnectionProviderInitiator.getConnectionProperties( props );
+ loadDriverClass( jdbcDriverClass );
+
+ autocommit = getBoolean( JdbcSettings.AUTOCOMMIT, properties ); // defaults to false
+ isolation = ConnectionProviderInitiator.extractIsolation( properties );
+
+ final Properties connectionProps = ConnectionProviderInitiator.getConnectionProperties( properties );
+ final Map poolSettings = poolSettings( properties );
+ dataSource = createDataSource( jdbcUrl, connectionProps, poolSettings );
+
+ dbInfoProducer = dialect -> new DatabaseConnectionInfoImpl(
+ jdbcUrl,
+ jdbcDriverClass,
+ dialect.getVersion(),
+ Boolean.toString( autocommit ),
+ isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null,
+ requireNonNullElse( getInteger( C3P0_STYLE_MIN_POOL_SIZE.substring( 5 ), poolSettings ),
+ DEFAULT_MIN_POOL_SIZE ),
+ requireNonNullElse( getInteger( C3P0_STYLE_MAX_POOL_SIZE.substring( 5 ), poolSettings ),
+ DEFAULT_MAX_POOL_SIZE )
+ );
+ }
- autocommit = getBoolean( JdbcSettings.AUTOCOMMIT, props );
+ private DataSource createDataSource(String jdbcUrl, Properties connectionProps, Map poolProperties) {
+ try {
+ return pooledDataSource( unpooledDataSource( jdbcUrl, connectionProps ), poolProperties );
+ }
+ catch (Exception e) {
+ ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
+ throw new ConnectionProviderConfigurationException(
+ "Could not configure c3p0: " + e.getMessage(), e );
+ }
+ }
+ private void loadDriverClass(String jdbcDriverClass) {
if ( jdbcDriverClass == null ) {
ConnectionInfoLogger.INSTANCE.jdbcDriverNotSpecified();
}
@@ -140,79 +187,59 @@ public void configure(Map props) {
throw new ClassLoadingException( "JDBC Driver class " + jdbcDriverClass + " not found", e );
}
}
+ }
- Integer minPoolSize = null;
- Integer maxPoolSize = null;
- try {
-
- //swaldman 2004-02-07: modify to allow null values to signify fall through to c3p0 PoolConfig defaults
- minPoolSize = getInteger( C3p0Settings.C3P0_MIN_SIZE, props );
- maxPoolSize = getInteger( C3p0Settings.C3P0_MAX_SIZE, props );
- final Integer maxIdleTime = getInteger( C3p0Settings.C3P0_TIMEOUT, props );
- final Integer maxStatements = getInteger( C3p0Settings.C3P0_MAX_STATEMENTS, props );
- final Integer acquireIncrement = getInteger( C3p0Settings.C3P0_ACQUIRE_INCREMENT, props );
- final Integer idleTestPeriod = getInteger( C3p0Settings.C3P0_IDLE_TEST_PERIOD, props );
-
- final Properties c3props = new Properties();
-
- // turn hibernate.c3p0.* into c3p0.*, so c3p0
- // gets a chance to see all hibernate.c3p0.*
- for ( String key : props.keySet() ) {
- if ( key.startsWith( HIBERNATE_STYLE_SETTING_PREFIX ) ) {
- final String newKey = key.substring( HIBERNATE_STYLE_SETTING_PREFIX.length() );
- if ( props.containsKey( newKey ) ) {
- warnPropertyConflict( key, newKey );
- }
- c3props.put( newKey, props.get( key ) );
+ private Map poolSettings(Map hibernateProperties) {
+ //swaldman 2004-02-07: modify to allow null values to signify fall through to c3p0 PoolConfig defaults
+ Integer maxPoolSize = getInteger( C3P0_MAX_SIZE, hibernateProperties );
+ if ( maxPoolSize == null ) {
+ // if hibernate.c3p0.max_size is not specified, use hibernate.connection.pool_size
+ maxPoolSize = getInteger( JdbcSettings.POOL_SIZE, hibernateProperties );
+ }
+ final Integer minPoolSize = getInteger( C3P0_MIN_SIZE, hibernateProperties );
+ final Integer maxIdleTime = getInteger( C3P0_TIMEOUT, hibernateProperties );
+ final Integer maxStatements = getInteger( C3P0_MAX_STATEMENTS, hibernateProperties );
+ final Integer acquireIncrement = getInteger( C3P0_ACQUIRE_INCREMENT, hibernateProperties );
+ final Integer idleTestPeriod = getInteger( C3P0_IDLE_TEST_PERIOD, hibernateProperties );
+
+ final Map c3p0Properties = new HashMap<>();
+ // turn hibernate.c3p0.* into c3p0.*, so c3p0
+ // gets a chance to see all hibernate.c3p0.*
+ for ( String key : hibernateProperties.keySet() ) {
+ if ( key.startsWith( HIBERNATE_STYLE_SETTING_PREFIX ) ) {
+ final String newKey = key.substring( HIBERNATE_STYLE_SETTING_PREFIX.length() );
+ if ( hibernateProperties.containsKey( newKey ) ) {
+ warnPropertyConflict( key, newKey );
}
+ c3p0Properties.put( newKey, hibernateProperties.get( key ) );
}
-
- setOverwriteProperty( C3p0Settings.C3P0_MIN_SIZE, C3P0_STYLE_MIN_POOL_SIZE, props, c3props, minPoolSize );
- setOverwriteProperty( C3p0Settings.C3P0_MAX_SIZE, C3P0_STYLE_MAX_POOL_SIZE, props, c3props, maxPoolSize );
- setOverwriteProperty( C3p0Settings.C3P0_TIMEOUT, C3P0_STYLE_MAX_IDLE_TIME, props, c3props, maxIdleTime );
- setOverwriteProperty( C3p0Settings.C3P0_MAX_STATEMENTS, C3P0_STYLE_MAX_STATEMENTS, props, c3props, maxStatements );
- setOverwriteProperty( C3p0Settings.C3P0_ACQUIRE_INCREMENT, C3P0_STYLE_ACQUIRE_INCREMENT, props, c3props, acquireIncrement );
- setOverwriteProperty(
- C3p0Settings.C3P0_IDLE_TEST_PERIOD,
- C3P0_STYLE_IDLE_CONNECTION_TEST_PERIOD,
- props,
- c3props,
- idleTestPeriod
- );
-
- // revert to traditional hibernate behavior of setting initialPoolSize to minPoolSize
- // unless otherwise specified with a c3p0.*-style parameter.
- final Integer initialPoolSize = getInteger( C3P0_STYLE_INITIAL_POOL_SIZE, props );
- if ( initialPoolSize == null ) {
- setOverwriteProperty( "", C3P0_STYLE_INITIAL_POOL_SIZE, props, c3props, minPoolSize );
- }
-
- final DataSource unpooled = DataSources.unpooledDataSource( jdbcUrl, connectionProps );
-
- final Map allProps = new HashMap<>();
- allProps.putAll( props );
- allProps.putAll( PropertiesHelper.map(c3props) );
-
- ds = DataSources.pooledDataSource( unpooled, allProps );
- }
- catch (Exception e) {
- ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
- throw new HibernateException( e );
}
- isolation = ConnectionProviderInitiator.extractIsolation( props );
+ setOverwriteProperty( C3P0_MIN_SIZE, C3P0_STYLE_MIN_POOL_SIZE,
+ hibernateProperties, c3p0Properties, minPoolSize );
+ setOverwriteProperty( C3P0_MAX_SIZE, C3P0_STYLE_MAX_POOL_SIZE,
+ hibernateProperties, c3p0Properties, maxPoolSize );
+ setOverwriteProperty( C3P0_TIMEOUT, C3P0_STYLE_MAX_IDLE_TIME,
+ hibernateProperties, c3p0Properties, maxIdleTime );
+ setOverwriteProperty( C3P0_MAX_STATEMENTS, C3P0_STYLE_MAX_STATEMENTS,
+ hibernateProperties, c3p0Properties, maxStatements );
+ setOverwriteProperty( C3P0_ACQUIRE_INCREMENT, C3P0_STYLE_ACQUIRE_INCREMENT,
+ hibernateProperties, c3p0Properties, acquireIncrement );
+ setOverwriteProperty( C3P0_IDLE_TEST_PERIOD, C3P0_STYLE_IDLE_CONNECTION_TEST_PERIOD,
+ hibernateProperties, c3p0Properties, idleTestPeriod );
+
+ // revert to traditional behavior of setting initialPoolSize to minPoolSize
+ // unless otherwise specified with a c3p0.*-style parameter
+ final Integer initialPoolSize = getInteger( C3P0_STYLE_INITIAL_POOL_SIZE, hibernateProperties );
+ if ( initialPoolSize == null ) {
+ setOverwriteProperty( "", C3P0_STYLE_INITIAL_POOL_SIZE,
+ hibernateProperties, c3p0Properties, minPoolSize );
+ }
- final Integer poolMinSize = minPoolSize;
- final Integer poolMaxSize = maxPoolSize;
- dbInfoProducer = (dialect) -> new DatabaseConnectionInfoImpl(
- jdbcUrl,
- jdbcDriverClass,
- dialect.getVersion(),
- Boolean.toString( autocommit ),
- isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null,
- poolMinSize,
- poolMaxSize
- );
+ final Map aggregatedProperties = new HashMap<>();
+ aggregatedProperties.putAll( hibernateProperties );
+ aggregatedProperties.putAll( c3p0Properties );
+ return aggregatedProperties;
}
@Override
@@ -228,17 +255,17 @@ public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
private void setOverwriteProperty(
String hibernateStyleKey,
String c3p0StyleKey,
- Map hibp,
- Properties c3p,
+ Map hibernateProperties,
+ Map c3p0Properties,
Integer value) {
if ( value != null ) {
final String peeledC3p0Key = c3p0StyleKey.substring( 5 );
- c3p.put( peeledC3p0Key, String.valueOf( value ).trim() );
- if ( hibp.containsKey( c3p0StyleKey ) ) {
+ c3p0Properties.put( peeledC3p0Key, String.valueOf( value ).trim() );
+ if ( hibernateProperties.containsKey( c3p0StyleKey ) ) {
warnPropertyConflict( hibernateStyleKey, c3p0StyleKey );
}
final String longC3p0StyleKey = "hibernate." + c3p0StyleKey;
- if ( hibp.containsKey( longC3p0StyleKey ) ) {
+ if ( hibernateProperties.containsKey( longC3p0StyleKey ) ) {
warnPropertyConflict( hibernateStyleKey, longC3p0StyleKey );
}
}
@@ -250,26 +277,15 @@ private void warnPropertyConflict(String hibernateStyle, String c3p0Style) {
@Override
public void stop() {
- ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( C3p0Settings.C3P0_CONFIG_PREFIX );
+ ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( C3P0_CONFIG_PREFIX );
try {
- DataSources.destroy( ds );
+ DataSources.destroy( dataSource );
}
catch (SQLException sqle) {
ConnectionInfoLogger.INSTANCE.unableToDestroyConnectionPool( sqle );
}
}
- /**
- * Close the provider.
- *
- * @deprecated Use {@link #stop} instead
- */
- @SuppressWarnings("unused")
- @Deprecated
- public void close() {
- stop();
- }
-
@Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
this.serviceRegistry = serviceRegistry;
diff --git a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0MessageLogger.java b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0MessageLogger.java
index bd98ab0e12f6..2d0b80dd0f3c 100644
--- a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0MessageLogger.java
+++ b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0MessageLogger.java
@@ -41,7 +41,7 @@ public interface C3P0MessageLogger extends ConnectionInfoLogger {
* @param c3p0Style The {@code c3p0.} prefixed setting
*/
@LogMessage(level = WARN)
- @Message(value = "Both hibernate-style property '%1$s' and c3p0-style property '%2$s' have been set in Hibernate "
- + "properties. Hibernate-style property '%1$s' will be used and c3p0-style property '%2$s' will be ignored!", id = 10001)
+ @Message(value = "Both hibernate-style property '%1$s' and c3p0-style property '%2$s' have been set in Hibernate properties.\n"
+ + "Hibernate-style property '%1$s' will be used and c3p0-style property '%2$s' will be ignored", id = 10001)
void bothHibernateAndC3p0StylesSet(String hibernateStyle,String c3p0Style);
}
diff --git a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/StrategyRegistrationProviderImpl.java b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/StrategyRegistrationProviderImpl.java
index f2e9f273990f..f2a83e067ee7 100644
--- a/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/StrategyRegistrationProviderImpl.java
+++ b/hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/StrategyRegistrationProviderImpl.java
@@ -20,7 +20,6 @@
public final class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
@Override
- @SuppressWarnings("unchecked")
public Iterable getStrategyRegistrations() {
final SimpleStrategyRegistrationImpl c3p0 = new SimpleStrategyRegistrationImpl<>(
ConnectionProvider.class,
diff --git a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3P0ProxyConnectionProvider.java b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3P0ProxyConnectionProvider.java
index 072a7f8b555d..49b91fcd9192 100644
--- a/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3P0ProxyConnectionProvider.java
+++ b/hibernate-c3p0/src/test/java/org/hibernate/test/c3p0/C3P0ProxyConnectionProvider.java
@@ -48,7 +48,7 @@ public void configure(Map props) {
throw new IllegalStateException( e );
}
- ReflectionUtil.setField( this, "ds", dataSource );
+ ReflectionUtil.setField( this, "dataSource", dataSource );
}
@Override
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java
index 28ba5645da0a..909d56ec8e8d 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java
@@ -240,11 +240,12 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
String CONNECTION_PROVIDER = "hibernate.connection.provider_class";
/**
- * Specifies the maximum number of inactive connections for the built-in
- * {@linkplain org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl
- * connection pool}.
- *
- * @settingDefault 20
+ * Specifies the maximum number of inactive connections for any
+ * {@linkplain ConnectionProvider connection pool} which respects this
+ * setting, including every built-in implementation except for
+ * {@link org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl}.
+ *
+ * The default pool size depends on the connection provider.
*/
String POOL_SIZE = "hibernate.connection.pool_size";
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java
index 00f8d5ee7be9..6f2a470b282f 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/ConnectionProviderInitiator.java
@@ -17,9 +17,9 @@
import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
-import org.hibernate.internal.util.StringHelper;
import org.hibernate.resource.beans.container.spi.BeanContainer;
import org.hibernate.resource.beans.internal.Helper;
import org.hibernate.service.spi.ServiceRegistryImplementor;
@@ -43,6 +43,7 @@
import static org.hibernate.cfg.JdbcSettings.USER;
import static org.hibernate.cfg.SchemaToolingSettings.ENABLE_SYNONYMS;
import static org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.isMultiTenancyEnabled;
+import static org.hibernate.internal.util.StringHelper.isBlank;
import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
/**
@@ -325,29 +326,38 @@ public static Integer interpretIsolation(Object setting) {
return null;
}
else if ( setting instanceof Number number ) {
- return number.intValue();
+ final int isolationLevel = number.intValue();
+ checkIsolationLevel( isolationLevel );
+ return isolationLevel;
}
else {
final String string = setting.toString();
- if ( StringHelper.isEmpty( string ) ) {
+ if ( isBlank( string ) ) {
return null;
}
else if ( ISOLATION_VALUE_MAP.containsKey( string ) ) {
return ISOLATION_VALUE_MAP.get( string );
}
else {
- // it could be a String representation of the isolation numeric value...
+ // it could be a String representation of the isolation numeric value
try {
- return Integer.valueOf( string );
+ final int isolationLevel = Integer.parseInt( string );
+ checkIsolationLevel( isolationLevel );
+ return isolationLevel;
}
catch (NumberFormatException ignore) {
+ throw new ConnectionProviderConfigurationException( "Unknown transaction isolation level: '" + string + "'" );
}
-
- throw new HibernateException("Could not interpret transaction isolation setting [" + setting + "]");
}
}
}
+ private static void checkIsolationLevel(int isolationLevel) {
+ if ( !ISOLATION_VALUE_CONSTANT_NAME_MAP.containsKey( isolationLevel ) ) {
+ throw new ConnectionProviderConfigurationException( "Unknown transaction isolation level: " + isolationLevel );
+ }
+ }
+
/**
* Gets the {@link Connection} constant name corresponding to the given isolation.
*
@@ -399,8 +409,9 @@ public interface SettingConsumer {
public static void consumeSetting(Map settings, SettingConsumer consumer, String... names) {
for ( String name : names ) {
- if ( settings.containsKey(name) ) {
- consumer.consumeSetting( name, (String) settings.get(name) );
+ final Object setting = settings.get( name );
+ if ( setting != null ) {
+ consumer.consumeSetting( name, setting.toString() );
return;
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DatasourceConnectionProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DatasourceConnectionProviderImpl.java
index 2ecd5e5fd46a..547c80de115e 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DatasourceConnectionProviderImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DatasourceConnectionProviderImpl.java
@@ -14,6 +14,7 @@
import org.hibernate.cfg.JdbcSettings;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.engine.jndi.spi.JndiService;
import org.hibernate.internal.log.ConnectionInfoLogger;
@@ -70,7 +71,7 @@ public boolean isUnwrappableAs(Class> unwrapType) {
}
@Override
- @SuppressWarnings( {"unchecked"})
+ @SuppressWarnings("unchecked")
public T unwrap(Class unwrapType) {
if ( ConnectionProvider.class.equals( unwrapType )
|| DatasourceConnectionProviderImpl.class.isAssignableFrom( unwrapType ) ) {
@@ -88,26 +89,23 @@ else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
public void configure(Map configValues) {
if ( dataSource == null ) {
final Object dataSourceSetting = configValues.get( DATASOURCE );
- if ( dataSourceSetting instanceof DataSource ds ) {
- dataSource = ds;
+ if ( dataSourceSetting instanceof DataSource instance ) {
+ dataSource = instance;
}
- else {
- final String dataSourceJndiName = (String) dataSourceSetting;
- if ( dataSourceJndiName == null ) {
- throw new HibernateException(
- "DataSource to use was not injected nor specified by [" + DATASOURCE
- + "] configuration property"
- );
- }
- this.dataSourceJndiName = dataSourceJndiName;
+ else if ( dataSourceSetting instanceof String jndiName ) {
+ dataSourceJndiName = jndiName;
if ( jndiService == null ) {
- throw new HibernateException( "Unable to locate JndiService to lookup Datasource" );
+ throw new ConnectionProviderConfigurationException( "Unable to locate JndiService to lookup Datasource" );
}
- dataSource = (DataSource) jndiService.locate( dataSourceJndiName );
+ dataSource = (DataSource) jndiService.locate( jndiName );
+ }
+ else {
+ throw new ConnectionProviderConfigurationException(
+ "DataSource to use was not injected nor specified by '" + DATASOURCE + "'" );
}
}
if ( dataSource == null ) {
- throw new HibernateException( "Unable to determine appropriate DataSource to use" );
+ throw new ConnectionProviderConfigurationException( "Unable to determine appropriate DataSource to use" );
}
if ( configValues.containsKey( AvailableSettings.AUTOCOMMIT ) ) {
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
index 90e3adb28102..b640b51d1007 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/internal/DriverManagerConnectionProviderImpl.java
@@ -28,6 +28,7 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SimpleDatabaseVersion;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.util.config.ConfigurationHelper;
import org.hibernate.service.UnknownUnwrapTypeException;
@@ -90,11 +91,8 @@ private PooledConnections buildPool(Map configurationValues, Serv
final int maxSize = ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 );
final int initialSize = ConfigurationHelper.getInt( INITIAL_SIZE, configurationValues, minSize );
- ConnectionCreator connectionCreator = buildCreator( configurationValues, serviceRegistry );
- PooledConnections.Builder pooledConnectionBuilder = new PooledConnections.Builder(
- connectionCreator,
- autoCommit
- );
+ final ConnectionCreator creator = buildCreator( configurationValues, serviceRegistry );
+ final PooledConnections.Builder pooledConnectionBuilder = new PooledConnections.Builder( creator, autoCommit );
pooledConnectionBuilder.initialSize( initialSize );
pooledConnectionBuilder.minSize( minSize );
pooledConnectionBuilder.maxSize( maxSize );
@@ -102,8 +100,9 @@ private PooledConnections buildPool(Map configurationValues, Serv
return pooledConnectionBuilder.build();
}
- private static ConnectionCreator buildCreator(Map configurationValues, ServiceRegistryImplementor serviceRegistry) {
- final String url = (String) configurationValues.get( AvailableSettings.URL );
+ private static ConnectionCreator buildCreator(
+ Map configurationValues, ServiceRegistryImplementor serviceRegistry) {
+ final String url = jdbcUrl( configurationValues );
String driverClassName = (String) configurationValues.get( AvailableSettings.DRIVER );
boolean success = false;
@@ -112,14 +111,14 @@ private static ConnectionCreator buildCreator(Map configurationVa
driver = loadDriverIfPossible( driverClassName, serviceRegistry );
success = true;
}
- else if ( url != null ) {
+ else {
//try to guess the driver class from the JDBC URL
for ( Database database: Database.values() ) {
if ( database.matchesUrl( url ) ) {
driverClassName = database.getDriverClassName( url );
if ( driverClassName != null ) {
try {
- loadDriverIfPossible(driverClassName, serviceRegistry);
+ loadDriverIfPossible( driverClassName, serviceRegistry );
success = true;
}
catch (Exception e) {
@@ -132,22 +131,7 @@ else if ( url != null ) {
}
}
- StringBuilder list = new StringBuilder();
- if ( !success ) {
- //we're hoping that the driver is already loaded
- ConnectionInfoLogger.INSTANCE.jdbcDriverNotSpecified();
- Enumeration drivers = DriverManager.getDrivers();
- while ( drivers.hasMoreElements() ) {
- if ( list.length() != 0) {
- list.append(", ");
- }
- list.append( drivers.nextElement().getClass().getName() );
- }
- }
-
- if ( url == null ) {
- throw new HibernateException( "No JDBC URL specified by property " + JAKARTA_JDBC_URL );
- }
+ final String driverList = success ? driverClassName : driverList();
final Properties connectionProps = ConnectionProviderInitiator.getConnectionProperties( configurationValues );
@@ -155,26 +139,16 @@ else if ( url != null ) {
final Integer isolation = ConnectionProviderInitiator.extractIsolation( configurationValues );
final String initSql = (String) configurationValues.get( INIT_SQL );
- final Object connectionCreatorFactory = configurationValues.get( CONNECTION_CREATOR_FACTORY );
- ConnectionCreatorFactory factory = null;
- if ( connectionCreatorFactory instanceof ConnectionCreatorFactory ) {
- factory = (ConnectionCreatorFactory) connectionCreatorFactory;
- }
- else if ( connectionCreatorFactory != null ) {
- factory = loadConnectionCreatorFactory( connectionCreatorFactory.toString(), serviceRegistry );
- }
- if ( factory == null ) {
- factory = ConnectionCreatorFactoryImpl.INSTANCE;
- }
+ final ConnectionCreatorFactory factory = getConnectionCreatorFactory( configurationValues, serviceRegistry );
dbInfo = new DatabaseConnectionInfoImpl(
url,
- success ? driverClassName : list.toString(),
+ driverList,
SimpleDatabaseVersion.ZERO_VERSION,
Boolean.toString( autoCommit ),
- isolation != null ? ConnectionProviderInitiator.toIsolationNiceName(isolation) : null,
- ConfigurationHelper.getInt(MIN_SIZE, configurationValues, 1),
- ConfigurationHelper.getInt(AvailableSettings.POOL_SIZE, configurationValues, 20)
+ isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null,
+ ConfigurationHelper.getInt( MIN_SIZE, configurationValues, 1 ),
+ ConfigurationHelper.getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 )
);
return factory.create(
@@ -189,15 +163,53 @@ else if ( connectionCreatorFactory != null ) {
);
}
+ private static String driverList() {
+ //we're hoping that the driver is already loaded
+ ConnectionInfoLogger.INSTANCE.jdbcDriverNotSpecified();
+ final StringBuilder list = new StringBuilder();
+ final Enumeration drivers = DriverManager.getDrivers();
+ while ( drivers.hasMoreElements() ) {
+ if ( !list.isEmpty() ) {
+ list.append(", ");
+ }
+ list.append( drivers.nextElement().getClass().getName() );
+ }
+ return list.toString();
+ }
+
+ private static String jdbcUrl(Map configurationValues) {
+ final String url = (String) configurationValues.get( AvailableSettings.URL );
+ if ( url == null ) {
+ throw new ConnectionProviderConfigurationException( "No JDBC URL specified by property '" + JAKARTA_JDBC_URL + "'" );
+ }
+ return url;
+ }
+
+ private static ConnectionCreatorFactory getConnectionCreatorFactory(
+ Map configurationValues, ServiceRegistryImplementor serviceRegistry) {
+ final Object connectionCreatorFactory = configurationValues.get( CONNECTION_CREATOR_FACTORY );
+ final ConnectionCreatorFactory factory;
+ if ( connectionCreatorFactory instanceof ConnectionCreatorFactory instance ) {
+ factory = instance;
+ }
+ else if ( connectionCreatorFactory != null ) {
+ factory = loadConnectionCreatorFactory( connectionCreatorFactory.toString(), serviceRegistry );
+ }
+ else {
+ factory = null;
+ }
+ return factory == null ? ConnectionCreatorFactoryImpl.INSTANCE : factory;
+ }
+
private static Driver loadDriverIfPossible(String driverClassName, ServiceRegistryImplementor serviceRegistry) {
if ( driverClassName == null ) {
ConnectionInfoLogger.INSTANCE.debug( "No driver class specified" );
return null;
}
-
- if ( serviceRegistry != null ) {
- final ClassLoaderService classLoaderService = serviceRegistry.requireService( ClassLoaderService.class );
- final Class driverClass = classLoaderService.classForName( driverClassName );
+ else if ( serviceRegistry != null ) {
+ final Class driverClass =
+ serviceRegistry.requireService( ClassLoaderService.class )
+ .classForName( driverClassName );
try {
return driverClass.newInstance();
}
@@ -205,22 +217,23 @@ private static Driver loadDriverIfPossible(String driverClassName, ServiceRegist
throw new ServiceException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e );
}
}
-
- try {
- return (Driver) Class.forName( driverClassName ).newInstance();
- }
- catch ( Exception e1 ) {
- throw new ServiceException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e1 );
+ else {
+ try {
+ return (Driver) Class.forName( driverClassName ).newInstance();
+ }
+ catch (Exception e1) {
+ throw new ServiceException( "Specified JDBC Driver " + driverClassName + " could not be loaded", e1 );
+ }
}
}
- private static ConnectionCreatorFactory loadConnectionCreatorFactory(String connectionCreatorFactoryClassName, ServiceRegistryImplementor serviceRegistry) {
+ private static ConnectionCreatorFactory loadConnectionCreatorFactory(
+ String connectionCreatorFactoryClassName, ServiceRegistryImplementor serviceRegistry) {
if ( connectionCreatorFactoryClassName == null ) {
ConnectionInfoLogger.INSTANCE.debug( "No connection creator factory class specified" );
return null;
}
-
- if ( serviceRegistry != null ) {
+ else if ( serviceRegistry != null ) {
final ClassLoaderService classLoaderService = serviceRegistry.requireService( ClassLoaderService.class );
final Class factoryClass =
classLoaderService.classForName( connectionCreatorFactoryClassName );
@@ -231,12 +244,15 @@ private static ConnectionCreatorFactory loadConnectionCreatorFactory(String conn
throw new ServiceException( "Specified ConnectionCreatorFactory " + connectionCreatorFactoryClassName + " could not be loaded", e );
}
}
-
- try {
- return (ConnectionCreatorFactory) Class.forName( connectionCreatorFactoryClassName ).newInstance();
- }
- catch ( Exception e1 ) {
- throw new ServiceException( "Specified ConnectionCreatorFactory " + connectionCreatorFactoryClassName + " could not be loaded", e1 );
+ else {
+ try {
+ return (ConnectionCreatorFactory) Class.forName( connectionCreatorFactoryClassName ).newInstance();
+ }
+ catch (Exception e1) {
+ throw new ServiceException(
+ "Specified ConnectionCreatorFactory " + connectionCreatorFactoryClassName + " could not be loaded",
+ e1 );
+ }
}
}
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProviderConfigurationException.java b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProviderConfigurationException.java
new file mode 100644
index 000000000000..d17ded15aa40
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/engine/jdbc/connections/spi/ConnectionProviderConfigurationException.java
@@ -0,0 +1,23 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ * Copyright Red Hat Inc. and Hibernate Authors
+ */
+package org.hibernate.engine.jdbc.connections.spi;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Occurs when there is a problem configuring a {@link ConnectionProvider}.
+ *
+ * @since 7.0
+ *
+ * @author Gavin King
+ */
+public class ConnectionProviderConfigurationException extends HibernateException {
+ public ConnectionProviderConfigurationException(String message) {
+ super( message );
+ }
+ public ConnectionProviderConfigurationException(String message, Throwable cause) {
+ super( message, cause );
+ }
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionInfoLogger.java b/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionInfoLogger.java
index d5ade897b282..f6c6eea9ece1 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionInfoLogger.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/log/ConnectionInfoLogger.java
@@ -66,7 +66,7 @@ public interface ConnectionInfoLogger extends BasicLogger {
void unableToDestroyConnectionPool(@Cause Exception e);
@LogMessage(level = DEBUG)
- @Message(value = "Could not instantiate connection pool", id = 10001011)
+ @Message(value = "Could not create connection pool", id = 10001011)
void unableToInstantiateConnectionPool(@Cause Exception e);
@LogMessage(level = DEBUG)
diff --git a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariCPConnectionProvider.java b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariCPConnectionProvider.java
index a4f6b073b4ef..16ab7c8b777e 100644
--- a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariCPConnectionProvider.java
+++ b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariCPConnectionProvider.java
@@ -4,8 +4,8 @@
*/
package org.hibernate.hikaricp.internal;
+import java.io.Serial;
import java.sql.Connection;
-import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import javax.sql.DataSource;
import java.util.Map;
@@ -14,9 +14,9 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.log.ConnectionInfoLogger;
-import org.hibernate.internal.util.StringHelper;
import org.hibernate.service.UnknownUnwrapTypeException;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.Stoppable;
@@ -25,45 +25,51 @@
import com.zaxxer.hikari.HikariDataSource;
import static org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.allowJdbcMetadataAccess;
+import static org.hibernate.hikaricp.internal.HikariConfigurationUtil.loadConfiguration;
+import static org.hibernate.internal.util.StringHelper.isBlank;
/**
- * HikariCP Connection provider for Hibernate.
+ * {@link ConnectionProvider} based on HikariCP connection pool.
+ *
+ * To force the use of this {@code ConnectionProvider} set
+ * {@value org.hibernate.cfg.JdbcSettings#CONNECTION_PROVIDER}
+ * to {@code hikari} or {@code hikaricp}.
*
* @author Brett Wooldridge
* @author Luca Burgazzoli
*/
public class HikariCPConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
+ @Serial
private static final long serialVersionUID = -9131625057941275711L;
private boolean isMetadataAccessAllowed = true;
/**
* HikariCP configuration.
*/
- private HikariConfig hcfg = null;
+ private HikariConfig hikariConfig = null;
/**
* HikariCP data source.
*/
- private HikariDataSource hds = null;
+ private HikariDataSource hikariDataSource = null;
// *************************************************************************
// Configurable
// *************************************************************************
@Override
- public void configure(Map props) throws HibernateException {
+ public void configure(Map configurationValues) throws HibernateException {
try {
- isMetadataAccessAllowed = allowJdbcMetadataAccess( props );
-
+ isMetadataAccessAllowed = allowJdbcMetadataAccess( configurationValues );
ConnectionInfoLogger.INSTANCE.configureConnectionPool( "HikariCP" );
-
- hcfg = HikariConfigurationUtil.loadConfiguration( props );
- hds = new HikariDataSource( hcfg );
+ hikariConfig = loadConfiguration( configurationValues );
+ hikariDataSource = new HikariDataSource( hikariConfig );
}
catch (Exception e) {
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
- throw new HibernateException( e );
+ throw new ConnectionProviderConfigurationException(
+ "Could not configure HikariCP: " + e.getMessage(), e );
}
}
@@ -73,7 +79,7 @@ public void configure(Map props) throws HibernateException {
@Override
public Connection getConnection() throws SQLException {
- return hds != null ? hds.getConnection() : null;
+ return hikariDataSource != null ? hikariDataSource.getConnection() : null;
}
@Override
@@ -89,23 +95,24 @@ public boolean supportsAggressiveRelease() {
@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
return new DatabaseConnectionInfoImpl(
- hcfg.getJdbcUrl(),
+ hikariConfig.getJdbcUrl(),
// Attempt to resolve the driver name from the dialect, in case it wasn't explicitly set and access to
// the database metadata is allowed
- !StringHelper.isBlank( hcfg.getDriverClassName() ) ? hcfg.getDriverClassName() : extractDriverNameFromMetadata(),
+ isBlank( hikariConfig.getDriverClassName() )
+ ? extractDriverNameFromMetadata()
+ : hikariConfig.getDriverClassName(),
dialect.getVersion(),
- Boolean.toString( hcfg.isAutoCommit() ),
- hcfg.getTransactionIsolation(),
- hcfg.getMinimumIdle(),
- hcfg.getMaximumPoolSize()
+ Boolean.toString( hikariConfig.isAutoCommit() ),
+ hikariConfig.getTransactionIsolation(),
+ hikariConfig.getMinimumIdle(),
+ hikariConfig.getMaximumPoolSize()
);
}
private String extractDriverNameFromMetadata() {
- if (isMetadataAccessAllowed) {
+ if ( isMetadataAccessAllowed ) {
try ( Connection conn = getConnection() ) {
- DatabaseMetaData dbmd = conn.getMetaData();
- return dbmd.getDriverName();
+ return conn.getMetaData().getDriverName();
}
catch (SQLException e) {
// Do nothing
@@ -129,7 +136,7 @@ public T unwrap(Class unwrapType) {
return (T) this;
}
else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
- return (T) hds;
+ return (T) hikariDataSource;
}
else {
throw new UnknownUnwrapTypeException( unwrapType );
@@ -142,9 +149,9 @@ else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
@Override
public void stop() {
- if ( hds != null ) {
+ if ( hikariDataSource != null ) {
ConnectionInfoLogger.INSTANCE.cleaningUpConnectionPool( "HikariCP" );
- hds.close();
+ hikariDataSource.close();
}
}
}
diff --git a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java
index 3ec65b9f3c41..6e99cbe589fa 100644
--- a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java
+++ b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/HikariConfigurationUtil.java
@@ -7,7 +7,6 @@
import java.util.Map;
import java.util.Properties;
-import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.HikariCPSettings;
import org.hibernate.cfg.JdbcSettings;
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
@@ -29,15 +28,17 @@ public class HikariConfigurationUtil {
/**
* Create/load a HikariConfig from Hibernate properties.
*
- * @param props a map of Hibernate properties
+ * @param properties a map of Hibernate properties
* @return a HikariConfig
*/
- public static HikariConfig loadConfiguration(Map props) {
- Properties hikariProps = new Properties();
- copyProperty( JdbcSettings.AUTOCOMMIT, props, "autoCommit", hikariProps );
+ public static HikariConfig loadConfiguration(Map properties) {
+ final Properties hikariProps = new Properties();
+ copyProperty( JdbcSettings.AUTOCOMMIT, properties, "autoCommit", hikariProps );
+
+ copyProperty( JdbcSettings.POOL_SIZE, properties, "maximumPoolSize", hikariProps );
copyProperty(
- props,
+ properties,
"driverClassName",
hikariProps,
JdbcSettings.JAKARTA_JDBC_DRIVER,
@@ -46,7 +47,7 @@ public static HikariConfig loadConfiguration(Map props) {
);
copyProperty(
- props,
+ properties,
"jdbcUrl",
hikariProps,
JdbcSettings.JAKARTA_JDBC_URL,
@@ -55,7 +56,7 @@ public static HikariConfig loadConfiguration(Map props) {
);
copyProperty(
- props,
+ properties,
"username",
hikariProps,
JdbcSettings.JAKARTA_JDBC_USER,
@@ -64,19 +65,20 @@ public static HikariConfig loadConfiguration(Map props) {
);
copyProperty(
- props,
+ properties,
"password",
hikariProps,
- AvailableSettings.JAKARTA_JDBC_PASSWORD,
- AvailableSettings.PASS,
- AvailableSettings.JPA_JDBC_PASSWORD
+ JdbcSettings.JAKARTA_JDBC_PASSWORD,
+ JdbcSettings.PASS,
+ JdbcSettings.JPA_JDBC_PASSWORD
);
- copyIsolationSetting( props, hikariProps );
+ copyIsolationSetting( properties, hikariProps );
- for ( String key : props.keySet() ) {
+ for ( var entry : properties.entrySet() ) {
+ final String key = entry.getKey();
if ( key.startsWith( CONFIG_PREFIX ) ) {
- hikariProps.setProperty( key.substring( CONFIG_PREFIX.length() ), (String) props.get( key ) );
+ hikariProps.setProperty( key.substring( CONFIG_PREFIX.length() ), entry.getValue().toString() );
}
}
@@ -85,7 +87,7 @@ public static HikariConfig loadConfiguration(Map props) {
private static void copyProperty(String srcKey, Map src, String dstKey, Properties dst) {
if ( src.containsKey( srcKey ) ) {
- dst.setProperty( dstKey, (String) src.get( srcKey ) );
+ dst.setProperty( dstKey, src.get( srcKey ).toString() );
}
}
@@ -100,10 +102,8 @@ private static void copyProperty(Map src, String dstKey, Properti
private static void copyIsolationSetting(Map props, Properties hikariProps) {
final Integer isolation = ConnectionProviderInitiator.extractIsolation( props );
if ( isolation != null ) {
- hikariProps.put(
- "transactionIsolation",
- ConnectionProviderInitiator.toIsolationConnectionConstantName( isolation )
- );
+ hikariProps.put( "transactionIsolation",
+ ConnectionProviderInitiator.toIsolationConnectionConstantName( isolation ) );
}
}
diff --git a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/StrategyRegistrationProviderImpl.java b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/StrategyRegistrationProviderImpl.java
index 0021d64f51ce..44416a7ebf04 100644
--- a/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/StrategyRegistrationProviderImpl.java
+++ b/hibernate-hikaricp/src/main/java/org/hibernate/hikaricp/internal/StrategyRegistrationProviderImpl.java
@@ -20,7 +20,6 @@
public final class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
@Override
- @SuppressWarnings("unchecked")
public Iterable getStrategyRegistrations() {
final SimpleStrategyRegistrationImpl strategyRegistration = new SimpleStrategyRegistrationImpl<>(
ConnectionProvider.class,
diff --git a/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/StrategyRegistrationProviderImpl.java b/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/StrategyRegistrationProviderImpl.java
index cbac650b60b4..4da10b815013 100644
--- a/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/StrategyRegistrationProviderImpl.java
+++ b/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/StrategyRegistrationProviderImpl.java
@@ -19,7 +19,7 @@
*/
public class StrategyRegistrationProviderImpl implements StrategyRegistrationProvider {
private static final List REGISTRATIONS = Collections.singletonList(
- (StrategyRegistration) new SimpleStrategyRegistrationImpl(
+ new SimpleStrategyRegistrationImpl<>(
ConnectionProvider.class,
UCPConnectionProvider.class,
"ucp",
@@ -30,7 +30,6 @@ public class StrategyRegistrationProviderImpl implements StrategyRegistrationPro
);
@Override
- @SuppressWarnings("unchecked")
public Iterable getStrategyRegistrations() {
return REGISTRATIONS;
}
diff --git a/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/UCPConnectionProvider.java b/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/UCPConnectionProvider.java
index def0fcecfe7e..871f77192792 100644
--- a/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/UCPConnectionProvider.java
+++ b/hibernate-ucp/src/main/java/org/hibernate/oracleucp/internal/UCPConnectionProvider.java
@@ -4,6 +4,7 @@
*/
package org.hibernate.oracleucp.internal;
+import java.io.Serial;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.SQLException;
@@ -20,6 +21,7 @@
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
+import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.internal.util.config.ConfigurationHelper;
@@ -36,32 +38,32 @@
public class UCPConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
+ @Serial
private static final long serialVersionUID = 1L;
private PoolDataSource ucpDS = null;
- private UniversalConnectionPoolManager poolManager = null;
private static final String UCP_CONFIG_PREFIX = "hibernate.oracleucp";
private static final String CONFIG_PREFIX = UCP_CONFIG_PREFIX + ".";
private boolean autoCommit;
private Integer isolation;
- @SuppressWarnings("rawtypes")
@Override
- public void configure(Map props) throws HibernateException {
+ public void configure(Map props) throws HibernateException {
try {
ConnectionInfoLogger.INSTANCE.configureConnectionPool( "Ucp" );
isolation = ConnectionProviderInitiator.extractIsolation( props );
autoCommit = ConfigurationHelper.getBoolean( AvailableSettings.AUTOCOMMIT, props );
- UniversalConnectionPoolManager poolManager = UniversalConnectionPoolManagerImpl.
- getUniversalConnectionPoolManager();
+ UniversalConnectionPoolManager poolManager =
+ UniversalConnectionPoolManagerImpl.getUniversalConnectionPoolManager();
ucpDS = PoolDataSourceFactory.getPoolDataSource();
Properties ucpProps = getConfiguration(props);
configureDataSource(ucpDS, ucpProps);
}
catch (Exception e) {
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
- throw new HibernateException( e );
+ throw new ConnectionProviderConfigurationException(
+ "Could not configure UCP: " + e.getMessage(), e );
}
}
@@ -128,13 +130,11 @@ private Properties getConfiguration(Map,?> props) {
copyProperty( AvailableSettings.USER, props, "user", ucpProps );
copyProperty( AvailableSettings.PASS, props, "password", ucpProps );
- for ( Object keyo : props.keySet() ) {
- if ( !(keyo instanceof String) ) {
- continue;
- }
- String key = (String) keyo;
- if ( key.startsWith( CONFIG_PREFIX ) ) {
- ucpProps.setProperty( key.substring( CONFIG_PREFIX.length() ), (String) props.get( key ) );
+ for ( Object object : props.keySet() ) {
+ if ( object instanceof String key ) {
+ if ( key.startsWith( CONFIG_PREFIX ) ) {
+ ucpProps.setProperty( key.substring( CONFIG_PREFIX.length() ), (String) props.get( key ) );
+ }
}
}