Skip to content

HHH-19702 ConnectionProvider rename #10729

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ service is defined by the interface (service role) +org.hibernate.engine.jdbc.co
which declares methods for obtaining and releasing the Connections. There are then multiple implementations of that
service contract, varying in how they actually manage the Connections:

* +org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl+ for using a +javax.sql.DataSource+
* +org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider+ for using a +javax.sql.DataSource+
* +org.hibernate.c3p0.internal.C3P0ConnectionProvider+ for using a C3P0 Connection pool
* etc.

Expand Down
12 changes: 6 additions & 6 deletions hibernate-core/src/main/java/org/hibernate/cfg/JdbcSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,12 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
* automatically:
* <ul>
* <li>if {@link #JAKARTA_JTA_DATASOURCE} or {@link #JAKARTA_NON_JTA_DATASOURCE}
* is set, {@linkplain org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl
* is set, {@linkplain org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider
* a datasource-based implementation} is used;
* <li>otherwise, a {@code ConnectionProvider} is loaded automatically as a
* {@linkplain java.util.ServiceLoader Java service};
* <li>but if no service is found, or if more than one service is available,
* {@linkplain org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl
* {@linkplain org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProvider
* a default implementation} is used as a fallback.
* </ul>
* <p>
Expand All @@ -266,7 +266,7 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
* 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}.
* {@link org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider}.
* <p>
* The default pool size depends on the connection provider.
*/
Expand All @@ -276,7 +276,7 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
* Specifies the JDBC transaction isolation level for connections obtained
* from any {@link ConnectionProvider} implementation which respects this
* setting, including every built-in implementation except for
* {@link org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl}.
* {@link org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider}.
* <p>
* Possible values are enumerated by {@link java.sql.Connection}:
* {@code READ_UNCOMMITTED}, {@code READ_COMMITTED},
Expand All @@ -293,7 +293,7 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
* Controls the autocommit mode of JDBC connections obtained from any
* {@link ConnectionProvider} implementation which respects this setting,
* including every built-in implementation except for
* {@link org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl}.
* {@link org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider}.
*
* @see java.sql.Connection#setAutoCommit(boolean)
*
Expand Down Expand Up @@ -329,7 +329,7 @@ public interface JdbcSettings extends C3p0Settings, AgroalSettings, HikariCPSett
* append {@code foo=bar} to the JDBC connection URL.
*
* @deprecated This setting is only supported by {@code C3P0ConnectionProvider}
* and {@link org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl}.
* and {@link org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProvider}.
*/
@Deprecated(since="7")
String CONNECTION_PREFIX = "hibernate.connection";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private ConnectionProvider instantiateNamedConnectionProvider(
private ConnectionProvider instantiateConnectionProvider(
Map<String, Object> configurationValues, StrategySelector strategySelector, BeanContainer beanContainer) {
if ( configurationValues.containsKey( DATASOURCE ) ) {
return new DatasourceConnectionProviderImpl();
return new DataSourceConnectionProvider();
}

final Class<? extends ConnectionProvider> singleRegisteredProvider =
Expand All @@ -163,7 +163,7 @@ else if ( hasConfiguration( configurationValues, AGROAL_CONFIG_PREFIX ) ) {
return instantiateProvider( strategySelector, AGROAL_STRATEGY );
}
else if ( configurationValues.containsKey( URL ) ) {
return new DriverManagerConnectionProviderImpl();
return new DriverManagerConnectionProvider();
}
else {
if ( beanContainer != null ) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.engine.jdbc.connections.internal;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import javax.sql.DataSource;

import org.hibernate.HibernateException;
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.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.engine.jndi.spi.JndiService;
import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.service.UnknownUnwrapTypeException;
import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.InjectService;
import org.hibernate.service.spi.Stoppable;

import static org.hibernate.cfg.JdbcSettings.DATASOURCE;
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.toIsolationNiceName;

/**
* A {@link ConnectionProvider} that manages connections from an underlying {@link DataSource}.
* <p>
* The {@link DataSource} to use may be specified by either:<ul>
* <li>injection using {@link #setDataSource},
* <li>passing the {@link DataSource} instance using {@value JdbcSettings#DATASOURCE},
* {@value JdbcSettings#JAKARTA_JTA_DATASOURCE}, or {@value JdbcSettings#JAKARTA_NON_JTA_DATASOURCE}, or
* <li>declaring the JNDI name under which the {@link DataSource} is found via {@value JdbcSettings#DATASOURCE},
* {@value JdbcSettings#JAKARTA_JTA_DATASOURCE}, or {@value JdbcSettings#JAKARTA_NON_JTA_DATASOURCE}.
* </ul>
*
* @author Gavin King
* @author Steve Ebersole
*/
public class DataSourceConnectionProvider
implements ConnectionProvider, Configurable, Stoppable {

private DataSource dataSource;
private String user;
private String pass;
private boolean useCredentials;
private JndiService jndiService;
private String dataSourceJndiName;

private boolean available;

public DataSource getDataSource() {
return dataSource;
}

public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

@InjectService( required = false )
@SuppressWarnings("unused")
public void setJndiService(JndiService jndiService) {
this.jndiService = jndiService;
}

@Override
public boolean isUnwrappableAs(Class<?> unwrapType) {
return unwrapType.isAssignableFrom( DataSourceConnectionProvider.class )
|| unwrapType.isAssignableFrom( DataSource.class);
}

@Override
@SuppressWarnings("unchecked")
public <T> T unwrap(Class<T> unwrapType) {
if ( unwrapType.isAssignableFrom( DataSourceConnectionProvider.class ) ) {
return (T) this;
}
else if ( unwrapType.isAssignableFrom( DataSource.class) ) {
return (T) getDataSource();
}
else {
throw new UnknownUnwrapTypeException( unwrapType );
}
}

@Override
public void configure(Map<String, Object> configuration) {
if ( dataSource == null ) {
final Object dataSourceSetting = configuration.get( DATASOURCE );
if ( dataSourceSetting instanceof DataSource instance ) {
dataSource = instance;
}
else if ( dataSourceSetting instanceof String jndiName ) {
dataSourceJndiName = jndiName;
if ( jndiService == null ) {
throw new ConnectionProviderConfigurationException( "Unable to locate JndiService to lookup Datasource" );
}
dataSource = (DataSource) jndiService.locate( jndiName );
}
else {
throw new ConnectionProviderConfigurationException(
"DataSource to use was not injected nor specified by '" + DATASOURCE + "'" );
}
}
if ( dataSource == null ) {
throw new ConnectionProviderConfigurationException( "Unable to determine appropriate DataSource to use" );
}

if ( configuration.containsKey( JdbcSettings.AUTOCOMMIT ) ) {
ConnectionInfoLogger.INSTANCE.ignoredSetting( JdbcSettings.AUTOCOMMIT,
DataSourceConnectionProvider.class );
}
if ( configuration.containsKey( JdbcSettings.ISOLATION ) ) {
ConnectionInfoLogger.INSTANCE.ignoredSetting( JdbcSettings.ISOLATION,
DataSourceConnectionProvider.class );
}

user = (String) configuration.get( JdbcSettings.USER );
pass = (String) configuration.get( JdbcSettings.PASS );
useCredentials = user != null || pass != null;
available = true;
}

@Override
public void stop() {
available = false;
dataSource = null;
}

@Override
public Connection getConnection() throws SQLException {
if ( !available ) {
throw new HibernateException( "Provider is closed" );
}
return useCredentials ? dataSource.getConnection( user, pass ) : dataSource.getConnection();
}

@Override
public void closeConnection(Connection connection) throws SQLException {
connection.close();
}

@Override
public boolean supportsAggressiveRelease() {
return true;
}

@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
return getDatabaseConnectionInfo( dialect, null );
}

@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect, ExtractedDatabaseMetaData metaData) {
return new DatabaseConnectionInfoImpl(
DataSourceConnectionProvider.class,
metaData == null ? null : metaData.getUrl(),
metaData == null ? null : metaData.getDriver(),
dialect.getClass(),
dialect.getVersion(),
metaData == null || metaData.supportsSchemas(),
metaData == null || metaData.supportsCatalogs(),
metaData == null ? null : metaData.getConnectionSchemaName(),
metaData == null ? null : metaData.getConnectionCatalogName(),
null,
metaData == null ? null : isolationString( metaData ),
null,
null,
metaData != null ? fetchSize( metaData ) : null
) {
@Override
public String toInfoString() {
return dataSourceJndiName != null
? "\tDataSource JNDI name [" + dataSourceJndiName + "]\n" + super.toInfoString()
: super.toInfoString();
}
};
}

private static Integer fetchSize(ExtractedDatabaseMetaData metaData) {
final int defaultFetchSize = metaData.getDefaultFetchSize();
return defaultFetchSize == -1 ? null : defaultFetchSize;
}

private String isolationString(ExtractedDatabaseMetaData metaData) {
return toIsolationNiceName( metaData.getTransactionIsolation() )
+ " [default " + toIsolationNiceName( metaData.getDefaultTransactionIsolation() ) + "]";
}
}
Loading