HHH-18989 log more info when DataSource is used

get it from the DatabaseMetaData
This commit is contained in:
Gavin King 2024-12-28 11:58:12 +01:00
parent aea72cccd5
commit a6aeeba8fe
12 changed files with 320 additions and 41 deletions

View File

@ -12,13 +12,14 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo; import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.internal.util.NullnessHelper; import org.hibernate.internal.util.NullnessHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.internal.util.config.ConfigurationHelper;
import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION; import static org.hibernate.dialect.SimpleDatabaseVersion.ZERO_VERSION;
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.interpretIsolation; import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.interpretIsolation;
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.toIsolationNiceName; import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.toIsolationNiceName;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.nullIfEmpty; import static org.hibernate.internal.util.StringHelper.nullIfEmpty;
import static org.hibernate.internal.util.config.ConfigurationHelper.getString;
/** /**
* Standard implementation of {@link DatabaseConnectionInfo} * Standard implementation of {@link DatabaseConnectionInfo}
@ -122,7 +123,7 @@ public class DatabaseConnectionInfoImpl implements DatabaseConnectionInfo {
} }
private static String handleEmpty(String value) { private static String handleEmpty(String value) {
return StringHelper.isNotEmpty( value ) ? value : DEFAULT; return isNotEmpty( value ) ? value : DEFAULT;
} }
private static String handleEmpty(DatabaseVersion dialectVersion) { private static String handleEmpty(DatabaseVersion dialectVersion) {
@ -141,23 +142,23 @@ public class DatabaseConnectionInfoImpl implements DatabaseConnectionInfo {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private static String determineUrl(Map<String, Object> settings) { private static String determineUrl(Map<String, Object> settings) {
return NullnessHelper.coalesceSuppliedValues( return NullnessHelper.coalesceSuppliedValues(
() -> ConfigurationHelper.getString( JdbcSettings.JAKARTA_JDBC_URL, settings ), () -> getString( JdbcSettings.JAKARTA_JDBC_URL, settings ),
() -> ConfigurationHelper.getString( JdbcSettings.URL, settings ), () -> getString( JdbcSettings.URL, settings ),
() -> ConfigurationHelper.getString( JdbcSettings.JPA_JDBC_URL, settings ) () -> getString( JdbcSettings.JPA_JDBC_URL, settings )
); );
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private static String determineDriver(Map<String, Object> settings) { private static String determineDriver(Map<String, Object> settings) {
return NullnessHelper.coalesceSuppliedValues( return NullnessHelper.coalesceSuppliedValues(
() -> ConfigurationHelper.getString( JdbcSettings.JAKARTA_JDBC_DRIVER, settings ), () -> getString( JdbcSettings.JAKARTA_JDBC_DRIVER, settings ),
() -> ConfigurationHelper.getString( JdbcSettings.DRIVER, settings ), () -> getString( JdbcSettings.DRIVER, settings ),
() -> ConfigurationHelper.getString( JdbcSettings.JPA_JDBC_DRIVER, settings ) () -> getString( JdbcSettings.JPA_JDBC_DRIVER, settings )
); );
} }
private static String determineAutoCommitMode(Map<String, Object> settings) { private static String determineAutoCommitMode(Map<String, Object> settings) {
return ConfigurationHelper.getString( JdbcSettings.AUTOCOMMIT, settings ); return getString( JdbcSettings.AUTOCOMMIT, settings );
} }
private static String determineIsolationLevel(Map<String, Object> settings) { private static String determineIsolationLevel(Map<String, Object> settings) {

View File

@ -16,6 +16,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException; import org.hibernate.engine.jdbc.connections.spi.ConnectionProviderConfigurationException;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo; 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.engine.jndi.spi.JndiService;
import org.hibernate.internal.log.ConnectionInfoLogger; import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.service.UnknownUnwrapTypeException; import org.hibernate.service.UnknownUnwrapTypeException;
@ -24,6 +25,7 @@ import org.hibernate.service.spi.InjectService;
import org.hibernate.service.spi.Stoppable; import org.hibernate.service.spi.Stoppable;
import static org.hibernate.cfg.JdbcSettings.DATASOURCE; 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}. * A {@link ConnectionProvider} that manages connections from an underlying {@link DataSource}.
@ -40,6 +42,7 @@ import static org.hibernate.cfg.JdbcSettings.DATASOURCE;
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class DatasourceConnectionProviderImpl implements ConnectionProvider, Configurable, Stoppable { public class DatasourceConnectionProviderImpl implements ConnectionProvider, Configurable, Stoppable {
private DataSource dataSource; private DataSource dataSource;
private String user; private String user;
private String pass; private String pass;
@ -149,21 +152,41 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
@Override @Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) { public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
return getDatabaseConnectionInfo( dialect, null );
}
@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect, ExtractedDatabaseMetaData metaData) {
final String url;
final String driver;
final String isolationLevel;
if ( metaData != null ) {
url = metaData.getUrl();
driver = metaData.getDriver();
isolationLevel = toIsolationNiceName( metaData.getTransactionIsolation() )
+ " [default " + toIsolationNiceName( metaData.getDefaultTransactionIsolation() ) + "]";
}
else {
url = null;
driver = null;
isolationLevel = null;
}
return new DatabaseConnectionInfoImpl( return new DatabaseConnectionInfoImpl(
DatasourceConnectionProviderImpl.class, DatasourceConnectionProviderImpl.class,
null, url,
null, driver,
dialect.getVersion(), dialect.getVersion(),
null, null,
null, isolationLevel,
null, null,
null null
) { ) {
@Override @Override
public String toInfoString() { public String toInfoString() {
return dataSourceJndiName != null return dataSourceJndiName != null
? "\tDatasource JNDI name [" + dataSourceJndiName + "]" ? "\tDataSource JNDI name [" + dataSourceJndiName + "]\n" + super.toInfoString()
: "\tProvided DataSource"; : super.toInfoString();
} }
}; };
} }

View File

@ -38,6 +38,7 @@ import org.hibernate.service.spi.Stoppable;
import org.hibernate.internal.log.ConnectionInfoLogger; import org.hibernate.internal.log.ConnectionInfoLogger;
import static org.hibernate.cfg.JdbcSettings.JAKARTA_JDBC_URL; import static org.hibernate.cfg.JdbcSettings.JAKARTA_JDBC_URL;
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.toIsolationNiceName;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean; import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
import static org.hibernate.internal.util.config.ConfigurationHelper.getInt; import static org.hibernate.internal.util.config.ConfigurationHelper.getInt;
import static org.hibernate.internal.util.config.ConfigurationHelper.getLong; import static org.hibernate.internal.util.config.ConfigurationHelper.getLong;
@ -148,7 +149,7 @@ public class DriverManagerConnectionProviderImpl
driverList, driverList,
SimpleDatabaseVersion.ZERO_VERSION, SimpleDatabaseVersion.ZERO_VERSION,
Boolean.toString( autoCommit ), Boolean.toString( autoCommit ),
isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null, isolation != null ? toIsolationNiceName( isolation ) : null,
getInt( MIN_SIZE, configurationValues, 1 ), getInt( MIN_SIZE, configurationValues, 1 ),
getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 ) getInt( AvailableSettings.POOL_SIZE, configurationValues, 20 )
); );

View File

@ -9,6 +9,7 @@ import java.sql.SQLException;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl; import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.service.Service; import org.hibernate.service.Service;
import org.hibernate.service.spi.Wrapped; import org.hibernate.service.spi.Wrapped;
@ -71,8 +72,21 @@ public interface ConnectionProvider extends Service, Wrapped {
*/ */
boolean supportsAggressiveRelease(); boolean supportsAggressiveRelease();
/**
* @return an informative instance of {@link DatabaseConnectionInfo} for logging.
*
* @since 6.6
*/
default DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) { default DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
return new DatabaseConnectionInfoImpl( dialect ); return new DatabaseConnectionInfoImpl( dialect );
} }
/**
* @return an informative instance of {@link DatabaseConnectionInfo} for logging.
*
* @since 7.0
*/
default DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect, ExtractedDatabaseMetaData metaData) {
return getDatabaseConnectionInfo( dialect );
}
} }

View File

@ -44,6 +44,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
private final boolean supportsDataDefinitionInTransaction; private final boolean supportsDataDefinitionInTransaction;
private final boolean doesDataDefinitionCauseTransactionCommit; private final boolean doesDataDefinitionCauseTransactionCommit;
private final SQLStateType sqlStateType; private final SQLStateType sqlStateType;
private final int transactionIsolation;
private final int defaultTransactionIsolation;
private final String url;
private final String driver;
private final boolean jdbcMetadataAccessible; private final boolean jdbcMetadataAccessible;
@ -65,6 +69,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
boolean supportsDataDefinitionInTransaction, boolean supportsDataDefinitionInTransaction,
boolean doesDataDefinitionCauseTransactionCommit, boolean doesDataDefinitionCauseTransactionCommit,
SQLStateType sqlStateType, SQLStateType sqlStateType,
int transactionIsolation,
int defaultTransactionIsolation,
String url,
String driver,
boolean jdbcMetadataIsAccessible) { boolean jdbcMetadataIsAccessible) {
this.jdbcEnvironment = jdbcEnvironment; this.jdbcEnvironment = jdbcEnvironment;
this.connectionAccess = connectionAccess; this.connectionAccess = connectionAccess;
@ -78,6 +86,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction; this.supportsDataDefinitionInTransaction = supportsDataDefinitionInTransaction;
this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit; this.doesDataDefinitionCauseTransactionCommit = doesDataDefinitionCauseTransactionCommit;
this.sqlStateType = sqlStateType; this.sqlStateType = sqlStateType;
this.transactionIsolation = transactionIsolation;
this.defaultTransactionIsolation = defaultTransactionIsolation;
this.url = url;
this.driver = driver;
this.jdbcMetadataAccessible = jdbcMetadataIsAccessible; this.jdbcMetadataAccessible = jdbcMetadataIsAccessible;
} }
@ -136,6 +148,26 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
return connectionSchemaName; return connectionSchemaName;
} }
@Override
public String getUrl() {
return url;
}
@Override
public String getDriver() {
return driver;
}
@Override
public int getTransactionIsolation() {
return transactionIsolation;
}
@Override
public int getDefaultTransactionIsolation() {
return defaultTransactionIsolation;
}
@Override @Override
public synchronized List<SequenceInformation> getSequenceInformationList() { public synchronized List<SequenceInformation> getSequenceInformationList() {
if ( jdbcMetadataAccessible ) { if ( jdbcMetadataAccessible ) {
@ -175,6 +207,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
private boolean supportsDataDefinitionInTransaction; private boolean supportsDataDefinitionInTransaction;
private boolean doesDataDefinitionCauseTransactionCommit; private boolean doesDataDefinitionCauseTransactionCommit;
private SQLStateType sqlStateType; private SQLStateType sqlStateType;
private String url;
private String driver;
private int defaultTransactionIsolation;
private int transactionIsolation;
public Builder(JdbcEnvironment jdbcEnvironment, boolean jdbcMetadataIsAccessible, JdbcConnectionAccess connectionAccess) { public Builder(JdbcEnvironment jdbcEnvironment, boolean jdbcMetadataIsAccessible, JdbcConnectionAccess connectionAccess) {
this.jdbcEnvironment = jdbcEnvironment; this.jdbcEnvironment = jdbcEnvironment;
@ -193,6 +229,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
supportsDataDefinitionInTransaction = !databaseMetaData.dataDefinitionIgnoredInTransactions(); supportsDataDefinitionInTransaction = !databaseMetaData.dataDefinitionIgnoredInTransactions();
doesDataDefinitionCauseTransactionCommit = databaseMetaData.dataDefinitionCausesTransactionCommit(); doesDataDefinitionCauseTransactionCommit = databaseMetaData.dataDefinitionCausesTransactionCommit();
sqlStateType = SQLStateType.interpretReportedSQLStateType( databaseMetaData.getSQLStateType() ); sqlStateType = SQLStateType.interpretReportedSQLStateType( databaseMetaData.getSQLStateType() );
url = databaseMetaData.getURL();
driver = databaseMetaData.getDriverName();
defaultTransactionIsolation = databaseMetaData.getDefaultTransactionIsolation();
transactionIsolation = databaseMetaData.getConnection().getTransactionIsolation();
return this; return this;
} }
@ -260,6 +300,10 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
supportsDataDefinitionInTransaction, supportsDataDefinitionInTransaction,
doesDataDefinitionCauseTransactionCommit, doesDataDefinitionCauseTransactionCommit,
sqlStateType, sqlStateType,
transactionIsolation,
defaultTransactionIsolation,
url,
driver,
jdbcMetadataIsAccessible jdbcMetadataIsAccessible
); );
} }

View File

@ -86,12 +86,12 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
final IdentifierHelperBuilder identifierHelperBuilder = final IdentifierHelperBuilder identifierHelperBuilder =
identifierHelperBuilder( cfgService, nameQualifierSupport ); identifierHelperBuilder( cfgService, nameQualifierSupport );
final ExtractedDatabaseMetaDataImpl.Builder dbMetaDataBuilder = final ExtractedDatabaseMetaDataImpl.Builder metaDataBuilder =
new ExtractedDatabaseMetaDataImpl.Builder( this, false, null ); new ExtractedDatabaseMetaDataImpl.Builder( this, false, null );
this.identifierHelper = identifierHelper( dialect, identifierHelperBuilder, dbMetaDataBuilder );; this.identifierHelper = identifierHelper( dialect, identifierHelperBuilder, metaDataBuilder );;
this.extractedMetaDataSupport = dbMetaDataBuilder.build(); this.extractedMetaDataSupport = metaDataBuilder.build();
this.currentCatalog = identifierHelper.toIdentifier( this.currentCatalog = identifierHelper.toIdentifier(
cfgService.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING ) cfgService.getSetting( AvailableSettings.DEFAULT_CATALOG, StandardConverters.STRING )

View File

@ -34,7 +34,6 @@ import org.hibernate.event.monitor.internal.EmptyEventMonitor;
import org.hibernate.event.monitor.spi.EventMonitor; import org.hibernate.event.monitor.spi.EventMonitor;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.ConnectionInfoLogger; import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.jdbc.AbstractReturningWork;
import org.hibernate.jpa.internal.MutableJpaComplianceImpl; import org.hibernate.jpa.internal.MutableJpaComplianceImpl;
import org.hibernate.jpa.spi.JpaCompliance; import org.hibernate.jpa.spi.JpaCompliance;
@ -50,6 +49,7 @@ import org.hibernate.stat.spi.StatisticsImplementor;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import static java.lang.Integer.parseInt;
import static org.hibernate.cfg.AvailableSettings.CONNECTION_HANDLING; import static org.hibernate.cfg.AvailableSettings.CONNECTION_HANDLING;
import static org.hibernate.cfg.AvailableSettings.DIALECT_DB_MAJOR_VERSION; import static org.hibernate.cfg.AvailableSettings.DIALECT_DB_MAJOR_VERSION;
import static org.hibernate.cfg.AvailableSettings.DIALECT_DB_MINOR_VERSION; import static org.hibernate.cfg.AvailableSettings.DIALECT_DB_MINOR_VERSION;
@ -69,6 +69,7 @@ import static org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.isMulti
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER; import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues; import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues;
import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty;
import static org.hibernate.internal.util.StringHelper.split;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean; import static org.hibernate.internal.util.config.ConfigurationHelper.getBoolean;
import static org.hibernate.internal.util.config.ConfigurationHelper.getBooleanWrapper; import static org.hibernate.internal.util.config.ConfigurationHelper.getBooleanWrapper;
import static org.hibernate.internal.util.config.ConfigurationHelper.getInteger; import static org.hibernate.internal.util.config.ConfigurationHelper.getInteger;
@ -100,8 +101,6 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
@Override @Override
public JdbcEnvironment initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) { public JdbcEnvironment initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
final DialectFactory dialectFactory = registry.requireService( DialectFactory.class );
final String explicitDatabaseName = getExplicitDatabaseName( configurationValues ); final String explicitDatabaseName = getExplicitDatabaseName( configurationValues );
Integer explicitDatabaseMajorVersion = getExplicitDatabaseMajorVersion( configurationValues ); Integer explicitDatabaseMajorVersion = getExplicitDatabaseMajorVersion( configurationValues );
Integer explicitDatabaseMinorVersion = getExplicitDatabaseMinorVersion( configurationValues ); Integer explicitDatabaseMinorVersion = getExplicitDatabaseMinorVersion( configurationValues );
@ -110,11 +109,11 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
getExplicitDatabaseVersion( configurationValues, explicitDatabaseMajorVersion, explicitDatabaseMinorVersion ); getExplicitDatabaseVersion( configurationValues, explicitDatabaseMajorVersion, explicitDatabaseMinorVersion );
if ( explicitDatabaseMajorVersion == null && explicitDatabaseMinorVersion == null && explicitDatabaseVersion != null ) { if ( explicitDatabaseMajorVersion == null && explicitDatabaseMinorVersion == null && explicitDatabaseVersion != null ) {
final String[] parts = StringHelper.split( ".", explicitDatabaseVersion ); final String[] parts = split( ".", explicitDatabaseVersion );
try { try {
final int potentialMajor = Integer.parseInt( parts[0] ); final int potentialMajor = parseInt( parts[0] );
if ( parts.length > 1 ) { if ( parts.length > 1 ) {
explicitDatabaseMinorVersion = Integer.parseInt( parts[1] ); explicitDatabaseMinorVersion = parseInt( parts[1] );
} }
explicitDatabaseMajorVersion = potentialMajor; explicitDatabaseMajorVersion = potentialMajor;
} }
@ -123,8 +122,27 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
} }
} }
return getJdbcEnvironment(
configurationValues,
registry,
explicitDatabaseName,
explicitDatabaseMajorVersion,
explicitDatabaseMinorVersion,
explicitDatabaseVersion
);
}
private JdbcEnvironment getJdbcEnvironment(
Map<String, Object> configurationValues,
ServiceRegistryImplementor registry,
String explicitDatabaseName,
Integer explicitDatabaseMajorVersion,
Integer explicitDatabaseMinorVersion,
String explicitDatabaseVersion) {
final DialectFactory dialectFactory = registry.requireService( DialectFactory.class );
final JdbcEnvironment jdbcEnvironment; final JdbcEnvironment jdbcEnvironment;
DatabaseConnectionInfo databaseConnectionInfo; final DatabaseConnectionInfo databaseConnectionInfo;
if ( allowJdbcMetadataAccess( configurationValues ) ) { if ( allowJdbcMetadataAccess( configurationValues ) ) {
jdbcEnvironment = getJdbcEnvironmentUsingJdbcMetadata( jdbcEnvironment = getJdbcEnvironmentUsingJdbcMetadata(
configurationValues, configurationValues,
@ -133,8 +151,9 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
explicitDatabaseName, explicitDatabaseName,
explicitDatabaseMajorVersion, explicitDatabaseMajorVersion,
explicitDatabaseMinorVersion, explicitDatabaseMinorVersion,
explicitDatabaseVersion); explicitDatabaseVersion
databaseConnectionInfo = buildDbInfo( registry, jdbcEnvironment.getDialect() ); );
databaseConnectionInfo = buildInfo( registry, jdbcEnvironment );
} }
else if ( explicitDialectConfiguration( explicitDatabaseName, configurationValues ) ) { else if ( explicitDialectConfiguration( explicitDatabaseName, configurationValues ) ) {
jdbcEnvironment = getJdbcEnvironmentWithExplicitConfiguration( jdbcEnvironment = getJdbcEnvironmentWithExplicitConfiguration(
@ -146,33 +165,31 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
explicitDatabaseMinorVersion, explicitDatabaseMinorVersion,
explicitDatabaseVersion explicitDatabaseVersion
); );
databaseConnectionInfo = buildDbInfo( configurationValues, jdbcEnvironment.getDialect() ); databaseConnectionInfo = buildInfo( configurationValues, jdbcEnvironment );
} }
else { else {
jdbcEnvironment = getJdbcEnvironmentWithDefaults( configurationValues, registry, dialectFactory ); jdbcEnvironment = getJdbcEnvironmentWithDefaults( configurationValues, registry, dialectFactory );
databaseConnectionInfo = buildDbInfo( configurationValues, jdbcEnvironment.getDialect() ); databaseConnectionInfo = buildInfo( configurationValues, jdbcEnvironment );
} }
// Standardized DB info logging // Standardized info logging
ConnectionInfoLogger.INSTANCE.logConnectionInfoDetails( databaseConnectionInfo.toInfoString() ); ConnectionInfoLogger.INSTANCE.logConnectionInfoDetails( databaseConnectionInfo.toInfoString() );
return jdbcEnvironment; return jdbcEnvironment;
} }
private DatabaseConnectionInfo buildDbInfo(ServiceRegistryImplementor registry, Dialect dialect) { private DatabaseConnectionInfo buildInfo(ServiceRegistryImplementor registry, JdbcEnvironment environment) {
if ( !isMultiTenancyEnabled( registry ) ) { if ( isMultiTenancyEnabled( registry ) ) {
return registry.requireService( ConnectionProvider.class ) return registry.requireService( MultiTenantConnectionProvider.class )
.getDatabaseConnectionInfo( dialect ); .getDatabaseConnectionInfo( environment.getDialect() );
} }
else { else {
final MultiTenantConnectionProvider<?> mcp = return registry.requireService( ConnectionProvider.class )
registry.requireService( MultiTenantConnectionProvider.class ); .getDatabaseConnectionInfo( environment.getDialect(), environment.getExtractedDatabaseMetaData() );
return mcp.getDatabaseConnectionInfo( dialect );
} }
} }
private DatabaseConnectionInfo buildDbInfo(Map<String, Object> configurationValues, Dialect dialect) { private DatabaseConnectionInfo buildInfo(Map<String, Object> configurationValues, JdbcEnvironment environment) {
return new DatabaseConnectionInfoImpl( configurationValues, dialect ); return new DatabaseConnectionInfoImpl( configurationValues, environment.getDialect() );
} }
private static JdbcEnvironmentImpl getJdbcEnvironmentWithDefaults( private static JdbcEnvironmentImpl getJdbcEnvironmentWithDefaults(
@ -372,7 +389,7 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
try { try {
final String substring = version.substring( prefix.length() ); final String substring = version.substring( prefix.length() );
final String micro = new StringTokenizer(substring," .,-:;/()[]").nextToken(); final String micro = new StringTokenizer(substring," .,-:;/()[]").nextToken();
return Integer.parseInt(micro); return parseInt(micro);
} }
catch (NumberFormatException nfe) { catch (NumberFormatException nfe) {
return 0; return 0;

View File

@ -122,6 +122,34 @@ public interface ExtractedDatabaseMetaData {
*/ */
SQLStateType getSqlStateType(); SQLStateType getSqlStateType();
/**
* Retrieve the JDBC URL.
*
* @see java.sql.DatabaseMetaData#getURL()
*/
String getUrl();
/**
* Retrieve the JDBC driver name.
*
* @see java.sql.DatabaseMetaData#getDriverName()
*/
String getDriver();
/**
* Retrieve the transaction isolation level.
*
* @see java.sql.Connection#getTransactionIsolation()
*/
int getTransactionIsolation();
/**
* Retrieve the default transaction isolation level.
*
* @see java.sql.DatabaseMetaData#getDefaultTransactionIsolation()
*/
int getDefaultTransactionIsolation();
/** /**
* Retrieve the list of {@code SequenceInformation} objects which describe the underlying database sequences. * Retrieve the list of {@code SequenceInformation} objects which describe the underlying database sequences.
* *

View File

@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.datasource;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.cfg.Environment;
import org.hibernate.cfg.JdbcSettings;
import org.hibernate.internal.log.ConnectionInfoLogger;
import org.hibernate.testing.logger.LogInspectionHelper;
import org.hibernate.testing.logger.LogListener;
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
import org.hibernate.testing.orm.junit.Jpa;
import org.hibernate.testing.orm.junit.Setting;
import org.jboss.logging.Logger;
import org.junit.jupiter.api.Test;
import java.util.Properties;
import static org.hibernate.internal.util.StringHelper.split;
import static org.junit.jupiter.api.Assertions.assertTrue;
@Jpa(annotatedClasses = DataSourceTest.TestEntity.class,
integrationSettings = @Setting(name = JdbcSettings.CONNECTION_PROVIDER,
value = "org.hibernate.orm.test.datasource.TestDataSourceConnectionProvider"))
public class DataSourceTest {
@Test
void test(EntityManagerFactoryScope scope) {
Listener listener = new Listener();
LogInspectionHelper.registerListener( listener, ConnectionInfoLogger.INSTANCE );
scope.getEntityManagerFactory();
LogInspectionHelper.clearAllListeners( ConnectionInfoLogger.INSTANCE );
assertTrue( listener.seen );
}
@Entity(name="TestEntity")
static class TestEntity {
@Id
long id;
}
private static class Listener implements LogListener {
boolean seen = false;
@Override
public void loggedEvent(Logger.Level level, String renderedMessage, Throwable thrown) {
if ( renderedMessage.contains( "Database info:" ) ) {
seen = true;
final Properties properties = Environment.getProperties();
assertTrue( renderedMessage.contains( split( ";", properties.getProperty(JdbcSettings.URL) )[0] ) );
}
}
}
}

View File

@ -0,0 +1,83 @@
/*
* SPDX-License-Identifier: LGPL-2.1-or-later
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.datasource;
import org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Map;
import java.util.logging.Logger;
public class TestDataSourceConnectionProvider
extends DatasourceConnectionProviderImpl
implements ServiceRegistryAwareService {
final DriverManagerConnectionProviderImpl delegate = new DriverManagerConnectionProviderImpl();
@Override
public void configure(Map<String, Object> configValues) {
delegate.configure(configValues);
setDataSource( new DataSource() {
PrintWriter logWriter = new PrintWriter( System.out );
@Override
public Connection getConnection() throws SQLException {
return delegate.getConnection();
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return delegate.getConnection();
}
@Override
public PrintWriter getLogWriter() {
return logWriter;
}
@Override
public void setLogWriter(PrintWriter out) {
this.logWriter = out;
}
@Override
public void setLoginTimeout(int seconds) {
}
@Override
public int getLoginTimeout() {
return -1;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return false;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
} );
super.configure( configValues );
}
@Override
public void injectServices(ServiceRegistryImplementor serviceRegistry) {
delegate.injectServices( serviceRegistry );
}
}

View File

@ -14,6 +14,7 @@ import org.hibernate.dialect.Dialect;
import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator; import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo; import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.service.spi.Configurable; import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryAwareService;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
@ -108,6 +109,11 @@ public class ConnectionProviderDelegate implements
return connectionProvider.getDatabaseConnectionInfo( dialect ); return connectionProvider.getDatabaseConnectionInfo( dialect );
} }
@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect, ExtractedDatabaseMetaData metaData) {
return connectionProvider.getDatabaseConnectionInfo( dialect, metaData );
}
@Override @Override
public boolean isUnwrappableAs(Class<?> unwrapType) { public boolean isUnwrappableAs(Class<?> unwrapType) {
return connectionProvider.isUnwrappableAs( unwrapType ); return connectionProvider.isUnwrappableAs( unwrapType );

View File

@ -56,6 +56,7 @@ import org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiato
import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl; import org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider; import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo; import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
import org.hibernate.engine.jdbc.env.spi.ExtractedDatabaseMetaData;
import org.hibernate.internal.build.AllowSysOut; import org.hibernate.internal.build.AllowSysOut;
import org.hibernate.service.spi.Configurable; import org.hibernate.service.spi.Configurable;
import org.hibernate.service.spi.ServiceRegistryAwareService; import org.hibernate.service.spi.ServiceRegistryAwareService;
@ -183,6 +184,11 @@ public class JtaAwareConnectionProviderImpl implements ConnectionProvider, Confi
return delegate.getDatabaseConnectionInfo( dialect ); return delegate.getDatabaseConnectionInfo( dialect );
} }
@Override
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect, ExtractedDatabaseMetaData metaData) {
return delegate.getDatabaseConnectionInfo( dialect, metaData );
}
protected Transaction findCurrentTransaction() { protected Transaction findCurrentTransaction() {
try { try {
return TestingJtaPlatformImpl.transactionManager().getTransaction(); return TestingJtaPlatformImpl.transactionManager().getTransaction();