HHH-18454 - Skip connection provider retrieval and DB info logging when booting offline
This commit is contained in:
parent
dc8a56be8f
commit
8190a1a6da
|
@ -7,16 +7,17 @@
|
||||||
|
|
||||||
package org.hibernate.agroal.internal;
|
package org.hibernate.agroal.internal;
|
||||||
|
|
||||||
import io.agroal.api.AgroalDataSource;
|
import java.sql.Connection;
|
||||||
import io.agroal.api.configuration.AgroalConnectionFactoryConfiguration;
|
import java.sql.SQLException;
|
||||||
import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
|
import java.util.Map;
|
||||||
import io.agroal.api.configuration.supplier.AgroalConnectionFactoryConfigurationSupplier;
|
import java.util.function.Consumer;
|
||||||
import io.agroal.api.configuration.supplier.AgroalPropertiesReader;
|
import java.util.function.Function;
|
||||||
import io.agroal.api.security.NamePrincipal;
|
import javax.sql.DataSource;
|
||||||
import io.agroal.api.security.SimplePassword;
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.cfg.AgroalSettings;
|
import org.hibernate.cfg.AgroalSettings;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
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.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
@ -26,12 +27,13 @@ import org.hibernate.service.UnknownUnwrapTypeException;
|
||||||
import org.hibernate.service.spi.Configurable;
|
import org.hibernate.service.spi.Configurable;
|
||||||
import org.hibernate.service.spi.Stoppable;
|
import org.hibernate.service.spi.Stoppable;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import io.agroal.api.AgroalDataSource;
|
||||||
import java.sql.Connection;
|
import io.agroal.api.configuration.AgroalConnectionFactoryConfiguration;
|
||||||
import java.sql.SQLException;
|
import io.agroal.api.configuration.AgroalConnectionPoolConfiguration;
|
||||||
import java.util.Map;
|
import io.agroal.api.configuration.supplier.AgroalConnectionFactoryConfigurationSupplier;
|
||||||
import java.util.function.Consumer;
|
import io.agroal.api.configuration.supplier.AgroalPropertiesReader;
|
||||||
import java.util.function.Function;
|
import io.agroal.api.security.NamePrincipal;
|
||||||
|
import io.agroal.api.security.SimplePassword;
|
||||||
|
|
||||||
import static org.hibernate.cfg.AgroalSettings.AGROAL_CONFIG_PREFIX;
|
import static org.hibernate.cfg.AgroalSettings.AGROAL_CONFIG_PREFIX;
|
||||||
|
|
||||||
|
@ -62,7 +64,6 @@ public class AgroalConnectionProvider implements ConnectionProvider, Configurabl
|
||||||
public static final String CONFIG_PREFIX = AGROAL_CONFIG_PREFIX + ".";
|
public static final String CONFIG_PREFIX = AGROAL_CONFIG_PREFIX + ".";
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private AgroalDataSource agroalDataSource = null;
|
private AgroalDataSource agroalDataSource = null;
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
|
|
||||||
// --- Configurable
|
// --- Configurable
|
||||||
|
|
||||||
|
@ -106,18 +107,6 @@ public class AgroalConnectionProvider implements ConnectionProvider, Configurabl
|
||||||
} ) );
|
} ) );
|
||||||
|
|
||||||
agroalDataSource = AgroalDataSource.from( agroalProperties );
|
agroalDataSource = AgroalDataSource.from( agroalProperties );
|
||||||
|
|
||||||
// For logging purposes
|
|
||||||
AgroalConnectionPoolConfiguration acpc = agroalDataSource.getConfiguration().connectionPoolConfiguration();
|
|
||||||
AgroalConnectionFactoryConfiguration acfc = acpc.connectionFactoryConfiguration();
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
|
||||||
.setDBUrl( acfc.jdbcUrl() )
|
|
||||||
.setDBDriverName( acfc.connectionProviderClass().toString() )
|
|
||||||
.setDBAutoCommitMode( Boolean.toString(acfc.autoCommit()) )
|
|
||||||
.setDBIsolationLevel( acfc.jdbcTransactionIsolation() != null ?
|
|
||||||
ConnectionProviderInitiator.toIsolationNiceName( acfc.jdbcTransactionIsolation().level() ) : null )
|
|
||||||
.setDBMinPoolSize( String.valueOf(acpc.minSize()) )
|
|
||||||
.setDBMaxPoolSize( String.valueOf(acpc.maxSize()) );
|
|
||||||
}
|
}
|
||||||
catch ( Exception e ) {
|
catch ( Exception e ) {
|
||||||
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
||||||
|
@ -146,8 +135,21 @@ public class AgroalConnectionProvider implements ConnectionProvider, Configurabl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
final AgroalConnectionPoolConfiguration acpc = agroalDataSource.getConfiguration().connectionPoolConfiguration();
|
||||||
|
final AgroalConnectionFactoryConfiguration acfc = acpc.connectionFactoryConfiguration();
|
||||||
|
|
||||||
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
acfc.jdbcUrl(),
|
||||||
|
acfc.connectionProviderClass().toString(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
Boolean.toString( acfc.autoCommit() ),
|
||||||
|
acfc.jdbcTransactionIsolation() != null
|
||||||
|
? ConnectionProviderInitiator.toIsolationNiceName( acfc.jdbcTransactionIsolation().level() )
|
||||||
|
: null,
|
||||||
|
acpc.minSize(),
|
||||||
|
acpc.minSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.DataSources;
|
import com.mchange.v2.c3p0.DataSources;
|
||||||
|
@ -20,6 +21,7 @@ import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||||
import org.hibernate.cfg.C3p0Settings;
|
import org.hibernate.cfg.C3p0Settings;
|
||||||
import org.hibernate.cfg.JdbcSettings;
|
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.ConnectionProviderInitiator;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
@ -62,11 +64,11 @@ public class C3P0ConnectionProvider
|
||||||
// hibernate sensibly lets default to minPoolSize, but we'll let users
|
// hibernate sensibly lets default to minPoolSize, but we'll let users
|
||||||
// override it with the c3p0-style property if they want.
|
// override it with the c3p0-style property if they want.
|
||||||
private static final String C3P0_STYLE_INITIAL_POOL_SIZE = "c3p0.initialPoolSize";
|
private static final String C3P0_STYLE_INITIAL_POOL_SIZE = "c3p0.initialPoolSize";
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
private DataSource ds;
|
private DataSource ds;
|
||||||
private Integer isolation;
|
private Integer isolation;
|
||||||
private boolean autocommit;
|
private boolean autocommit;
|
||||||
|
|
||||||
|
private Function<Dialect,DatabaseConnectionInfo> dbInfoProducer;
|
||||||
private ServiceRegistryImplementor serviceRegistry;
|
private ServiceRegistryImplementor serviceRegistry;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -202,13 +204,17 @@ public class C3P0ConnectionProvider
|
||||||
|
|
||||||
isolation = ConnectionProviderInitiator.extractIsolation( props );
|
isolation = ConnectionProviderInitiator.extractIsolation( props );
|
||||||
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
final Integer poolMinSize = minPoolSize;
|
||||||
.setDBUrl( jdbcUrl )
|
final Integer poolMaxSize = maxPoolSize;
|
||||||
.setDBDriverName( jdbcDriverClass )
|
dbInfoProducer = (dialect) -> new DatabaseConnectionInfoImpl(
|
||||||
.setDBAutoCommitMode( Boolean.toString( autocommit ) )
|
jdbcUrl,
|
||||||
.setDBIsolationLevel( isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null )
|
jdbcDriverClass,
|
||||||
.setDBMinPoolSize( String.valueOf(minPoolSize) )
|
dialect.getVersion(),
|
||||||
.setDBMaxPoolSize( String.valueOf(maxPoolSize) );
|
Boolean.toString( autocommit ),
|
||||||
|
isolation != null ? ConnectionProviderInitiator.toIsolationNiceName( isolation ) : null,
|
||||||
|
poolMinSize,
|
||||||
|
poolMaxSize
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -217,8 +223,8 @@ public class C3P0ConnectionProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
return dbInfoProducer.apply( dialect );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOverwriteProperty(
|
private void setOverwriteProperty(
|
||||||
|
|
|
@ -6,117 +6,156 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.engine.jdbc.connections.internal;
|
package org.hibernate.engine.jdbc.connections.internal;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.JdbcSettings;
|
||||||
import org.hibernate.dialect.DatabaseVersion;
|
import org.hibernate.dialect.DatabaseVersion;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
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.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
|
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.dialect.SimpleDatabaseVersion.NO_VERSION;
|
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.interpretIsolation;
|
||||||
|
import static org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator.toIsolationNiceName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Standard implementation of DatabaseConnectionInfo
|
||||||
|
*
|
||||||
* @author Jan Schatteman
|
* @author Jan Schatteman
|
||||||
*/
|
*/
|
||||||
public class DatabaseConnectionInfoImpl implements DatabaseConnectionInfo {
|
public class DatabaseConnectionInfoImpl implements DatabaseConnectionInfo {
|
||||||
|
|
||||||
// Means either the value was not explicitly set, or simply not offered by the connection provider
|
|
||||||
public static final String DEFAULT = "undefined/unknown";
|
public static final String DEFAULT = "undefined/unknown";
|
||||||
|
|
||||||
protected String dbUrl = DEFAULT;
|
protected final String jdbcUrl;
|
||||||
protected String dbDriverName = DEFAULT;
|
protected final String jdbcDriver;
|
||||||
protected DatabaseVersion dbVersion = ZERO_VERSION;
|
protected final DatabaseVersion dialectVersion;
|
||||||
protected String dbAutoCommitMode = DEFAULT;
|
protected final String autoCommitMode;
|
||||||
protected String dbIsolationLevel = DEFAULT;
|
protected final String isolationLevel;
|
||||||
protected String dbMinPoolSize = DEFAULT;
|
protected final Integer poolMinSize;
|
||||||
protected String dbMaxPoolSize = DEFAULT;
|
protected final Integer poolMaxSize;
|
||||||
|
|
||||||
public DatabaseConnectionInfoImpl() {
|
public DatabaseConnectionInfoImpl(
|
||||||
|
String jdbcUrl,
|
||||||
|
String jdbcDriver,
|
||||||
|
DatabaseVersion dialectVersion,
|
||||||
|
String autoCommitMode,
|
||||||
|
String isolationLevel,
|
||||||
|
Integer poolMinSize,
|
||||||
|
Integer poolMaxSize) {
|
||||||
|
this.jdbcUrl = jdbcUrl;
|
||||||
|
this.jdbcDriver = jdbcDriver;
|
||||||
|
this.dialectVersion = dialectVersion;
|
||||||
|
this.autoCommitMode = autoCommitMode;
|
||||||
|
this.isolationLevel = isolationLevel;
|
||||||
|
this.poolMinSize = poolMinSize;
|
||||||
|
this.poolMaxSize = poolMaxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConnectionInfoImpl(Map<String, Object> settings, Dialect dialect) {
|
||||||
|
this(
|
||||||
|
determineUrl( settings ),
|
||||||
|
determineDriver( settings ),
|
||||||
|
dialect.getVersion(),
|
||||||
|
determineAutoCommitMode( settings ),
|
||||||
|
determineIsolationLevel( settings ),
|
||||||
|
// No setting for min. pool size
|
||||||
|
null,
|
||||||
|
determinePoolMaxSize( settings )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatabaseConnectionInfoImpl(Dialect dialect) {
|
||||||
|
this( null, null, dialect.getVersion(), null, null, null, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBUrl(String dbUrl) {
|
public String getJdbcUrl() {
|
||||||
this.dbUrl = dbUrl;
|
return jdbcUrl;
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBDriverName(String dbDriverName) {
|
public String getJdbcDriver() {
|
||||||
if ( checkValidString(dbDriverName) && isDefaultStringValue(this.dbDriverName) ) {
|
return jdbcDriver;
|
||||||
this.dbDriverName = dbDriverName;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBVersion(DatabaseVersion dbVersion) {
|
public DatabaseVersion getDialectVersion() {
|
||||||
if ( checkValidVersion(dbVersion) && ZERO_VERSION.equals(this.dbVersion) ) {
|
return dialectVersion;
|
||||||
this.dbVersion = dbVersion;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBAutoCommitMode(String dbAutoCommitMode) {
|
public String getAutoCommitMode() {
|
||||||
if ( checkValidString(dbAutoCommitMode) && isDefaultStringValue(this.dbAutoCommitMode) ) {
|
return autoCommitMode;
|
||||||
this.dbAutoCommitMode = dbAutoCommitMode;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBIsolationLevel(String dbIsolationLevel) {
|
public String getIsolationLevel() {
|
||||||
if ( checkValidString(dbIsolationLevel) && isDefaultStringValue(this.dbIsolationLevel) ) {
|
return isolationLevel;
|
||||||
this.dbIsolationLevel = dbIsolationLevel;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBMinPoolSize(String minPoolSize) {
|
public Integer getPoolMinSize() {
|
||||||
if ( checkValidInteger(minPoolSize) ) {
|
return poolMinSize;
|
||||||
this.dbMinPoolSize = minPoolSize;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo setDBMaxPoolSize(String maxPoolSize) {
|
public Integer getPoolMaxSize() {
|
||||||
if ( checkValidInteger(maxPoolSize) ) {
|
return poolMaxSize;
|
||||||
this.dbMaxPoolSize = maxPoolSize;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkValidInteger(String integerString) {
|
|
||||||
try {
|
|
||||||
return checkValidString( integerString ) && Integer.parseInt( integerString, 10 ) >= 0;
|
|
||||||
}
|
|
||||||
catch (NumberFormatException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkValidString(String value) {
|
|
||||||
return !( StringHelper.isBlank( value ) || "null".equalsIgnoreCase( value ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkValidVersion(DatabaseVersion version) {
|
|
||||||
return version != null && !( version.isSame(ZERO_VERSION) || version.isSame(NO_VERSION) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isDefaultStringValue(String value) {
|
|
||||||
return DEFAULT.equalsIgnoreCase( value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDBInfoAsString() {
|
public String toInfoString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
return "\tDatabase JDBC URL [" + handleEmpty( jdbcUrl ) + ']' +
|
||||||
sb.append( "\tDatabase JDBC URL [" ).append( dbUrl ).append(']');
|
"\n\tDatabase driver: " + handleEmpty( jdbcDriver ) +
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Database driver: " ).append( dbDriverName );
|
"\n\tDatabase version: " + handleEmpty( dialectVersion ) +
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Database version: " ).append( dbVersion );
|
"\n\tAutocommit mode: " + handleEmpty( autoCommitMode ) +
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Autocommit mode: " ).append( dbAutoCommitMode );
|
"\n\tIsolation level: " + handleEmpty( isolationLevel ) +
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Isolation level: " ).append( dbIsolationLevel );
|
"\n\tMinimum pool size: " + handleEmpty( poolMinSize ) +
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Minimum pool size: " ).append( dbMinPoolSize );
|
"\n\tMaximum pool size: " + handleEmpty( poolMaxSize );
|
||||||
sb.append(sb.length() > 0 ? "\n\t" : "" ).append( "Maximum pool size: " ).append( dbMaxPoolSize );
|
}
|
||||||
return sb.toString();
|
|
||||||
|
private static String handleEmpty(String value) {
|
||||||
|
return StringHelper.isNotEmpty( value ) ? value : DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String handleEmpty(DatabaseVersion dialectVersion) {
|
||||||
|
return dialectVersion != null ? dialectVersion.toString() : ZERO_VERSION.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String handleEmpty(Integer value) {
|
||||||
|
return value != null ? value.toString() : DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private static String determineUrl(Map<String, Object> settings) {
|
||||||
|
return NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.JAKARTA_JDBC_URL, settings ),
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.URL, settings ),
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.JPA_JDBC_URL, settings )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private static String determineDriver(Map<String, Object> settings) {
|
||||||
|
return NullnessHelper.coalesceSuppliedValues(
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.JAKARTA_JDBC_DRIVER, settings ),
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.DRIVER, settings ),
|
||||||
|
() -> ConfigurationHelper.getString( JdbcSettings.JPA_JDBC_DRIVER, settings )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String determineAutoCommitMode(Map<String, Object> settings) {
|
||||||
|
return ConfigurationHelper.getString( JdbcSettings.AUTOCOMMIT, settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String determineIsolationLevel(Map<String, Object> settings) {
|
||||||
|
return toIsolationNiceName( interpretIsolation( settings.get(JdbcSettings.ISOLATION ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer determinePoolMaxSize(Map<String, Object> settings) {
|
||||||
|
return ConfigurationHelper.getInteger( JdbcSettings.POOL_SIZE, settings );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
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.engine.jndi.spi.JndiService;
|
import org.hibernate.engine.jndi.spi.JndiService;
|
||||||
|
@ -136,7 +137,15 @@ public class DatasourceConnectionProviderImpl implements ConnectionProvider, Con
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return new DatabaseConnectionInfoImpl().setDBUrl( "Connecting through datasource" + dataSourceJndiName );
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
"Connecting through datasource" + dataSourceJndiName,
|
||||||
|
null,
|
||||||
|
dialect.getVersion(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ import org.hibernate.Internal;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.dialect.Database;
|
import org.hibernate.dialect.Database;
|
||||||
|
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.ConnectionProvider;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
|
import org.hibernate.engine.jdbc.connections.spi.DatabaseConnectionInfo;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
|
@ -170,13 +172,15 @@ public class DriverManagerConnectionProviderImpl
|
||||||
factory = ConnectionCreatorFactoryImpl.INSTANCE;
|
factory = ConnectionCreatorFactoryImpl.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
dbInfo = new DatabaseConnectionInfoImpl(
|
||||||
.setDBUrl( url )
|
url,
|
||||||
.setDBDriverName( success ? driverClassName : list.toString() )
|
success ? driverClassName : list.toString(),
|
||||||
.setDBAutoCommitMode( Boolean.toString( autoCommit ) )
|
SimpleDatabaseVersion.ZERO_VERSION,
|
||||||
.setDBIsolationLevel( isolation != null ? ConnectionProviderInitiator.toIsolationNiceName(isolation) : null )
|
Boolean.toString( autoCommit ),
|
||||||
.setDBMinPoolSize( String.valueOf(ConfigurationHelper.getInt(MIN_SIZE, configurationValues, 1)) )
|
isolation != null ? ConnectionProviderInitiator.toIsolationNiceName(isolation) : null,
|
||||||
.setDBMaxPoolSize( String.valueOf(ConfigurationHelper.getInt(AvailableSettings.POOL_SIZE, configurationValues, 20)) );
|
ConfigurationHelper.getInt(MIN_SIZE, configurationValues, 1),
|
||||||
|
ConfigurationHelper.getInt(AvailableSettings.POOL_SIZE, configurationValues, 20)
|
||||||
|
);
|
||||||
|
|
||||||
return factory.create(
|
return factory.create(
|
||||||
|
|
||||||
|
@ -267,8 +271,16 @@ public class DriverManagerConnectionProviderImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
dbInfo.getJdbcUrl(),
|
||||||
|
dbInfo.getJdbcDriver(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
dbInfo.getAutoCommitMode(),
|
||||||
|
dbInfo.getIsolationLevel(),
|
||||||
|
dbInfo.getPoolMinSize(),
|
||||||
|
dbInfo.getPoolMaxSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.engine.jdbc.connections.spi;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
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,8 @@ public interface ConnectionProvider extends Service, Wrapped {
|
||||||
*/
|
*/
|
||||||
boolean supportsAggressiveRelease();
|
boolean supportsAggressiveRelease();
|
||||||
|
|
||||||
default DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
default DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return new DatabaseConnectionInfoImpl();
|
return new DatabaseConnectionInfoImpl( dialect );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import javax.sql.DataSource;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.MultiTenancySettings;
|
import org.hibernate.cfg.MultiTenancySettings;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.engine.jndi.spi.JndiService;
|
import org.hibernate.engine.jndi.spi.JndiService;
|
||||||
|
@ -48,8 +49,6 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl<T>
|
||||||
private T tenantIdentifierForAny;
|
private T tenantIdentifierForAny;
|
||||||
private String baseJndiNamespace;
|
private String baseJndiNamespace;
|
||||||
|
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected DataSource selectAnyDataSource() {
|
protected DataSource selectAnyDataSource() {
|
||||||
return selectDataSource( tenantIdentifierForAny );
|
return selectDataSource( tenantIdentifierForAny );
|
||||||
|
@ -62,7 +61,6 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl<T>
|
||||||
dataSource = (DataSource) jndiService.locate( baseJndiNamespace + '/' + tenantIdentifier );
|
dataSource = (DataSource) jndiService.locate( baseJndiNamespace + '/' + tenantIdentifier );
|
||||||
dataSourceMap().put( tenantIdentifier, dataSource );
|
dataSourceMap().put( tenantIdentifier, dataSource );
|
||||||
}
|
}
|
||||||
dbInfo = new DatabaseConnectionInfoImpl().setDBUrl( "Connecting through datasource" + baseJndiNamespace + '/' + tenantIdentifier );
|
|
||||||
return dataSource;
|
return dataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,8 +123,16 @@ public class DataSourceBasedMultiTenantConnectionProviderImpl<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
"Multi-tenant - " + tenantIdentifierForAny,
|
||||||
|
null,
|
||||||
|
dialect.getVersion(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,24 +7,64 @@
|
||||||
package org.hibernate.engine.jdbc.connections.spi;
|
package org.hibernate.engine.jdbc.connections.spi;
|
||||||
|
|
||||||
import org.hibernate.dialect.DatabaseVersion;
|
import org.hibernate.dialect.DatabaseVersion;
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Contract used for logging "database information" on bootstrap
|
||||||
|
*
|
||||||
|
* @apiNote Most of the getters here may return {@code null} which indicates the value is not known
|
||||||
|
*
|
||||||
* @author Jan Schatteman
|
* @author Jan Schatteman
|
||||||
*/
|
*/
|
||||||
public interface DatabaseConnectionInfo {
|
public interface DatabaseConnectionInfo {
|
||||||
DatabaseConnectionInfo setDBUrl(String dbUrl);
|
/**
|
||||||
|
* The JDBC URL to be used for connections
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getJdbcUrl();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBDriverName(String dbDriverName);
|
/**
|
||||||
|
* The JDBC Driver to be used for connections
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getJdbcDriver();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBVersion(DatabaseVersion dbVersion);
|
/**
|
||||||
|
* The database version.
|
||||||
|
*
|
||||||
|
* @see Dialect#getVersion()
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
DatabaseVersion getDialectVersion();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBAutoCommitMode(String dbAutoCommitMode);
|
/**
|
||||||
|
* The transaction auto-commit mode in effect.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getAutoCommitMode();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBIsolationLevel(String dbIsolationLevel);
|
/**
|
||||||
|
* The transaction isolation-level in effect.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getIsolationLevel();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBMinPoolSize(String minPoolSize);
|
/**
|
||||||
|
* The minimum connection pool size.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Integer getPoolMinSize();
|
||||||
|
|
||||||
DatabaseConnectionInfo setDBMaxPoolSize(String maxPoolSize);
|
/**
|
||||||
|
* The maximum connection pool size.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Integer getPoolMaxSize();
|
||||||
|
|
||||||
String getDBInfoAsString();
|
/**
|
||||||
|
* Collects the information available here as a single String with the intent of using it in logging.
|
||||||
|
*/
|
||||||
|
String toInfoString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ package org.hibernate.engine.jdbc.connections.spi;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import org.hibernate.dialect.Dialect;
|
||||||
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.service.Service;
|
import org.hibernate.service.Service;
|
||||||
import org.hibernate.service.spi.Wrapped;
|
import org.hibernate.service.spi.Wrapped;
|
||||||
|
@ -91,8 +92,8 @@ public interface MultiTenantConnectionProvider<T> extends Service, Wrapped {
|
||||||
*/
|
*/
|
||||||
boolean supportsAggressiveRelease();
|
boolean supportsAggressiveRelease();
|
||||||
|
|
||||||
default DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
default DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return new DatabaseConnectionInfoImpl();
|
return new DatabaseConnectionInfoImpl( dialect );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,7 +135,7 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
|
||||||
explicitDatabaseMajorVersion,
|
explicitDatabaseMajorVersion,
|
||||||
explicitDatabaseMinorVersion,
|
explicitDatabaseMinorVersion,
|
||||||
explicitDatabaseVersion);
|
explicitDatabaseVersion);
|
||||||
databaseConnectionInfo = buildDbInfo( registry );
|
databaseConnectionInfo = buildDbInfo( registry, jdbcEnvironment.getDialect() );
|
||||||
}
|
}
|
||||||
else if ( explicitDialectConfiguration( explicitDatabaseName, configurationValues ) ) {
|
else if ( explicitDialectConfiguration( explicitDatabaseName, configurationValues ) ) {
|
||||||
jdbcEnvironment = getJdbcEnvironmentWithExplicitConfiguration(
|
jdbcEnvironment = getJdbcEnvironmentWithExplicitConfiguration(
|
||||||
|
@ -147,42 +147,32 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
|
||||||
explicitDatabaseMinorVersion,
|
explicitDatabaseMinorVersion,
|
||||||
explicitDatabaseVersion
|
explicitDatabaseVersion
|
||||||
);
|
);
|
||||||
databaseConnectionInfo = buildDbInfo( configurationValues );
|
databaseConnectionInfo = buildDbInfo( configurationValues, jdbcEnvironment.getDialect() );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
jdbcEnvironment = getJdbcEnvironmentWithDefaults( configurationValues, registry, dialectFactory );
|
jdbcEnvironment = getJdbcEnvironmentWithDefaults( configurationValues, registry, dialectFactory );
|
||||||
databaseConnectionInfo = buildDbInfo( configurationValues );
|
databaseConnectionInfo = buildDbInfo( configurationValues, jdbcEnvironment.getDialect() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// most likely, the version hasn't been set yet, at least not for the ConnectionProviders that we currently maintain
|
|
||||||
databaseConnectionInfo.setDBVersion( jdbcEnvironment.getDialect().getVersion() );
|
|
||||||
|
|
||||||
// Standardized DB info logging
|
// Standardized DB info logging
|
||||||
ConnectionInfoLogger.INSTANCE.logConnectionInfoDetails( databaseConnectionInfo.getDBInfoAsString() );
|
ConnectionInfoLogger.INSTANCE.logConnectionInfoDetails( databaseConnectionInfo.toInfoString() );
|
||||||
|
|
||||||
return jdbcEnvironment;
|
return jdbcEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabaseConnectionInfo buildDbInfo(ServiceRegistryImplementor registry) {
|
private DatabaseConnectionInfo buildDbInfo(ServiceRegistryImplementor registry, Dialect dialect) {
|
||||||
if ( !isMultiTenancyEnabled( registry ) ) {
|
if ( !isMultiTenancyEnabled( registry ) ) {
|
||||||
final ConnectionProvider cp = registry.requireService( ConnectionProvider.class );
|
final ConnectionProvider cp = registry.requireService( ConnectionProvider.class );
|
||||||
return cp.getDatabaseConnectionInfo();
|
return cp.getDatabaseConnectionInfo( dialect );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final MultiTenantConnectionProvider<?> mcp = registry.getService( MultiTenantConnectionProvider.class );
|
final MultiTenantConnectionProvider<?> mcp = registry.requireService( MultiTenantConnectionProvider.class );
|
||||||
assert mcp != null;
|
return mcp.getDatabaseConnectionInfo( dialect );
|
||||||
return mcp.getDatabaseConnectionInfo();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DatabaseConnectionInfo buildDbInfo(Map<String, Object> configurationValues) {
|
private DatabaseConnectionInfo buildDbInfo(Map<String, Object> configurationValues, Dialect dialect) {
|
||||||
return new DatabaseConnectionInfoImpl()
|
return new DatabaseConnectionInfoImpl( configurationValues, dialect );
|
||||||
.setDBUrl( (String) configurationValues.get(JdbcSettings.JAKARTA_JDBC_URL) )
|
|
||||||
.setDBDriverName( (String) configurationValues.get(JdbcSettings.JAKARTA_JDBC_DRIVER) )
|
|
||||||
.setDBAutoCommitMode( (String) configurationValues.get(JdbcSettings.AUTOCOMMIT) )
|
|
||||||
.setDBIsolationLevel( ConnectionProviderInitiator.toIsolationNiceName( ConnectionProviderInitiator.interpretIsolation(configurationValues.get(JdbcSettings.ISOLATION)) ) )
|
|
||||||
// No setting for min. pool size
|
|
||||||
.setDBMaxPoolSize( (String) configurationValues.get(JdbcSettings.POOL_SIZE) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JdbcEnvironmentImpl getJdbcEnvironmentWithDefaults(
|
private static JdbcEnvironmentImpl getJdbcEnvironmentWithDefaults(
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html.
|
||||||
|
*/
|
||||||
|
package org.hibernate.orm.test.boot;
|
||||||
|
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.JdbcSettings;
|
||||||
|
import org.hibernate.dialect.H2Dialect;
|
||||||
|
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||||
|
import org.hibernate.internal.log.ConnectionInfoLogger;
|
||||||
|
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||||
|
|
||||||
|
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.DomainModel;
|
||||||
|
import org.hibernate.testing.orm.junit.Logger;
|
||||||
|
import org.hibernate.testing.orm.junit.LoggingInspections;
|
||||||
|
import org.hibernate.testing.orm.junit.LoggingInspectionsScope;
|
||||||
|
import org.hibernate.testing.orm.junit.MessageKeyInspection;
|
||||||
|
import org.hibernate.testing.orm.junit.MessageKeyWatcher;
|
||||||
|
import org.hibernate.testing.orm.junit.RequiresDialect;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||||
|
import org.hibernate.testing.orm.junit.ServiceRegistryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||||
|
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||||
|
import org.hibernate.testing.orm.junit.Setting;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test database info logging on bootstrap
|
||||||
|
*
|
||||||
|
* @implSpec This is limited to H2 so that we know what to expect from the logging
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||||
|
@MessageKeyInspection(
|
||||||
|
messageKey = "HHH10001005",
|
||||||
|
logger = @Logger( loggerName = ConnectionInfoLogger.LOGGER_NAME )
|
||||||
|
)
|
||||||
|
public class BootLoggingTests {
|
||||||
|
@Test
|
||||||
|
@ServiceRegistry( settings = @Setting( name = AvailableSettings.ALLOW_METADATA_ON_BOOT, value = "false" ) )
|
||||||
|
@DomainModel( standardModels = StandardDomainModel.HELPDESK )
|
||||||
|
@SessionFactory( exportSchema = false, generateStatistics = true )
|
||||||
|
@RequiresDialect( H2Dialect.class )
|
||||||
|
void testNoJdbcAccess(MessageKeyWatcher dbInfoLoggingWatcher, ServiceRegistryScope registryScope, SessionFactoryScope sessionFactoryScope) {
|
||||||
|
// make sure we get the db-info logged
|
||||||
|
assertThat( dbInfoLoggingWatcher.wasTriggered() ).isTrue();
|
||||||
|
|
||||||
|
// make sure it was logged as we expect
|
||||||
|
final ConfigurationService configurationService = registryScope.getRegistry().requireService( ConfigurationService.class );
|
||||||
|
assertThat( dbInfoLoggingWatcher.getTriggeredMessages() ).hasSize( 1 );
|
||||||
|
final String loggedMessage = dbInfoLoggingWatcher.getTriggeredMessages().get( 0 );
|
||||||
|
assertThat( loggedMessage ).contains( "Database JDBC URL [" + configurationService.getSettings().get( JdbcSettings.URL ) );
|
||||||
|
assertThat( loggedMessage ).contains( "Database driver: " + configurationService.getSettings().get( JdbcSettings.DRIVER ) );
|
||||||
|
assertThat( loggedMessage ).contains( "Maximum pool size: " + configurationService.getSettings().get( JdbcSettings.POOL_SIZE ) );
|
||||||
|
|
||||||
|
// and make sure we did not connect to the database
|
||||||
|
final StatisticsImplementor statistics = sessionFactoryScope.getSessionFactory().getStatistics();
|
||||||
|
assertThat( statistics.getConnectCount() ).isEqualTo( 0 );
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
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.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;
|
||||||
|
@ -44,8 +45,6 @@ public class HikariCPConnectionProvider implements ConnectionProvider, Configura
|
||||||
*/
|
*/
|
||||||
private HikariDataSource hds = null;
|
private HikariDataSource hds = null;
|
||||||
|
|
||||||
private DatabaseConnectionInfo dbinfo;
|
|
||||||
|
|
||||||
// *************************************************************************
|
// *************************************************************************
|
||||||
// Configurable
|
// Configurable
|
||||||
// *************************************************************************
|
// *************************************************************************
|
||||||
|
@ -57,14 +56,6 @@ public class HikariCPConnectionProvider implements ConnectionProvider, Configura
|
||||||
|
|
||||||
hcfg = HikariConfigurationUtil.loadConfiguration( props );
|
hcfg = HikariConfigurationUtil.loadConfiguration( props );
|
||||||
hds = new HikariDataSource( hcfg );
|
hds = new HikariDataSource( hcfg );
|
||||||
|
|
||||||
dbinfo = new DatabaseConnectionInfoImpl()
|
|
||||||
.setDBUrl( hcfg.getJdbcUrl() )
|
|
||||||
.setDBDriverName( hcfg.getDriverClassName() )
|
|
||||||
.setDBAutoCommitMode( Boolean.toString( hcfg.isAutoCommit() ) )
|
|
||||||
.setDBIsolationLevel( hcfg.getTransactionIsolation() )
|
|
||||||
.setDBMinPoolSize( String.valueOf(hcfg.getMinimumIdle()) )
|
|
||||||
.setDBMaxPoolSize( String.valueOf(hcfg.getMaximumPoolSize()) );
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
||||||
|
@ -92,8 +83,16 @@ public class HikariCPConnectionProvider implements ConnectionProvider, Configura
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbinfo;
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
hcfg.getJdbcUrl(),
|
||||||
|
hcfg.getDriverClassName(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
Boolean.toString( hcfg.isAutoCommit() ),
|
||||||
|
hcfg.getTransactionIsolation(),
|
||||||
|
hcfg.getMinimumIdle(),
|
||||||
|
hcfg.getMaximumPoolSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.hibernate.HibernateException;
|
||||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||||
import org.hibernate.cfg.JdbcSettings;
|
import org.hibernate.cfg.JdbcSettings;
|
||||||
import org.hibernate.cfg.ProxoolSettings;
|
import org.hibernate.cfg.ProxoolSettings;
|
||||||
|
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.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
@ -51,6 +52,7 @@ public class ProxoolConnectionProvider
|
||||||
|
|
||||||
private static final String PROXOOL_JDBC_STEM = "proxool.";
|
private static final String PROXOOL_JDBC_STEM = "proxool.";
|
||||||
|
|
||||||
|
private String proxoolPoolAlias;
|
||||||
private String proxoolAlias;
|
private String proxoolAlias;
|
||||||
|
|
||||||
// TRUE if the pool is borrowed from the outside, FALSE if we used to create it
|
// TRUE if the pool is borrowed from the outside, FALSE if we used to create it
|
||||||
|
@ -64,8 +66,6 @@ public class ProxoolConnectionProvider
|
||||||
|
|
||||||
private ClassLoaderService classLoaderService;
|
private ClassLoaderService classLoaderService;
|
||||||
|
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Connection getConnection() throws SQLException {
|
public Connection getConnection() throws SQLException {
|
||||||
// get a connection from the pool (through DriverManager, cfr. Proxool doc)
|
// get a connection from the pool (through DriverManager, cfr. Proxool doc)
|
||||||
|
@ -122,7 +122,6 @@ public class ProxoolConnectionProvider
|
||||||
final String propFile = (String) props.get( ProxoolSettings.PROXOOL_PROPERTIES );
|
final String propFile = (String) props.get( ProxoolSettings.PROXOOL_PROPERTIES );
|
||||||
final String externalConfig = (String) props.get( ProxoolSettings.PROXOOL_EXISTING_POOL );
|
final String externalConfig = (String) props.get( ProxoolSettings.PROXOOL_EXISTING_POOL );
|
||||||
|
|
||||||
String proxoolPoolAlias;
|
|
||||||
// Default the Proxool alias setting
|
// Default the Proxool alias setting
|
||||||
proxoolAlias = proxoolPoolAlias = (String) props.get( ProxoolSettings.PROXOOL_POOL_ALIAS );
|
proxoolAlias = proxoolPoolAlias = (String) props.get( ProxoolSettings.PROXOOL_POOL_ALIAS );
|
||||||
|
|
||||||
|
@ -193,21 +192,6 @@ public class ProxoolConnectionProvider
|
||||||
// Remember Isolation level
|
// Remember Isolation level
|
||||||
isolation = ConnectionProviderInitiator.extractIsolation( props );
|
isolation = ConnectionProviderInitiator.extractIsolation( props );
|
||||||
autocommit = getBoolean( JdbcSettings.AUTOCOMMIT, props );
|
autocommit = getBoolean( JdbcSettings.AUTOCOMMIT, props );
|
||||||
|
|
||||||
try {
|
|
||||||
ConnectionPoolDefinitionIF cpd = ProxoolFacade.getConnectionPoolDefinition( proxoolPoolAlias );
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
|
||||||
.setDBUrl( cpd.getUrl() )
|
|
||||||
.setDBDriverName( cpd.getDriver() )
|
|
||||||
.setDBIsolationLevel( ConnectionProviderInitiator.toIsolationNiceName(isolation) )
|
|
||||||
.setDBAutoCommitMode( Boolean.toString(autocommit) )
|
|
||||||
.setDBMinPoolSize( String.valueOf(cpd.getMinimumConnectionCount()) )
|
|
||||||
.setDBMaxPoolSize( String.valueOf(cpd.getMaximumConnectionCount()) );
|
|
||||||
}
|
|
||||||
catch (ProxoolException e) {
|
|
||||||
PROXOOL_MESSAGE_LOGGER.warn( "Error while obtaining the database pool information", e );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Reader getConfigStreamReader(String resource) {
|
private Reader getConfigStreamReader(String resource) {
|
||||||
|
@ -256,8 +240,23 @@ public class ProxoolConnectionProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
try {
|
||||||
|
final ConnectionPoolDefinitionIF cpd = ProxoolFacade.getConnectionPoolDefinition( proxoolPoolAlias );
|
||||||
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
cpd.getUrl(),
|
||||||
|
cpd.getDriver(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
ConnectionProviderInitiator.toIsolationNiceName( isolation ),
|
||||||
|
Boolean.toString( autocommit ),
|
||||||
|
cpd.getMinimumConnectionCount(),
|
||||||
|
cpd.getMaximumConnectionCount()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (ProxoolException e) {
|
||||||
|
PROXOOL_MESSAGE_LOGGER.warn( "Error while obtaining the database pool information", e );
|
||||||
|
return new DatabaseConnectionInfoImpl( dialect );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
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;
|
||||||
|
@ -105,8 +106,8 @@ public class ConnectionProviderDelegate implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return connectionProvider.getDatabaseConnectionInfo();
|
return connectionProvider.getDatabaseConnectionInfo( dialect );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -53,6 +53,7 @@ import javax.transaction.xa.Xid;
|
||||||
|
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
|
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.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;
|
||||||
|
@ -180,8 +181,8 @@ public class JtaAwareConnectionProviderImpl implements ConnectionProvider, Confi
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return delegate.getDatabaseConnectionInfo();
|
return delegate.getDatabaseConnectionInfo( dialect );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Transaction findCurrentTransaction() {
|
protected Transaction findCurrentTransaction() {
|
||||||
|
|
|
@ -15,10 +15,11 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
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.internal.DatabaseConnectionInfoImpl;
|
import org.hibernate.engine.jdbc.connections.internal.DatabaseConnectionInfoImpl;
|
||||||
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
|
||||||
|
@ -34,7 +35,6 @@ import oracle.ucp.admin.UniversalConnectionPoolManager;
|
||||||
import oracle.ucp.admin.UniversalConnectionPoolManagerImpl;
|
import oracle.ucp.admin.UniversalConnectionPoolManagerImpl;
|
||||||
import oracle.ucp.jdbc.PoolDataSource;
|
import oracle.ucp.jdbc.PoolDataSource;
|
||||||
import oracle.ucp.jdbc.PoolDataSourceFactory;
|
import oracle.ucp.jdbc.PoolDataSourceFactory;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
|
||||||
|
|
||||||
|
|
||||||
public class UCPConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
|
public class UCPConnectionProvider implements ConnectionProvider, Configurable, Stoppable {
|
||||||
|
@ -47,8 +47,6 @@ public class UCPConnectionProvider implements ConnectionProvider, Configurable,
|
||||||
private boolean autoCommit;
|
private boolean autoCommit;
|
||||||
private Integer isolation;
|
private Integer isolation;
|
||||||
|
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Override
|
@Override
|
||||||
public void configure(Map props) throws HibernateException {
|
public void configure(Map props) throws HibernateException {
|
||||||
|
@ -63,14 +61,6 @@ public class UCPConnectionProvider implements ConnectionProvider, Configurable,
|
||||||
ucpDS = PoolDataSourceFactory.getPoolDataSource();
|
ucpDS = PoolDataSourceFactory.getPoolDataSource();
|
||||||
Properties ucpProps = getConfiguration(props);
|
Properties ucpProps = getConfiguration(props);
|
||||||
configureDataSource(ucpDS, ucpProps);
|
configureDataSource(ucpDS, ucpProps);
|
||||||
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
|
||||||
.setDBUrl( ucpDS.getURL() )
|
|
||||||
.setDBDriverName( ucpDS.getConnectionFactoryClassName() )
|
|
||||||
.setDBAutoCommitMode( Boolean.toString( autoCommit ) )
|
|
||||||
.setDBIsolationLevel( isolation != null ? ConnectionProviderInitiator.toIsolationConnectionConstantName( isolation ) : null )
|
|
||||||
.setDBMinPoolSize( String.valueOf(ucpDS.getMinPoolSize()) )
|
|
||||||
.setDBMaxPoolSize( String.valueOf(ucpDS.getMaxPoolSize()) );
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
ConnectionInfoLogger.INSTANCE.unableToInstantiateConnectionPool( e );
|
||||||
|
@ -193,8 +183,16 @@ public class UCPConnectionProvider implements ConnectionProvider, Configurable,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
ucpDS.getURL(),
|
||||||
|
ucpDS.getConnectionFactoryClassName(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
Boolean.toString( autoCommit ),
|
||||||
|
isolation != null ? ConnectionProviderInitiator.toIsolationConnectionConstantName( isolation ) : null,
|
||||||
|
ucpDS.getMinPoolSize(),
|
||||||
|
ucpDS.getMaxPoolSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
|
|
||||||
package org.hibernate.vibur.internal;
|
package org.hibernate.vibur.internal;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
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.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;
|
||||||
|
@ -17,12 +23,12 @@ import org.hibernate.service.spi.Stoppable;
|
||||||
|
|
||||||
import org.vibur.dbcp.ViburDBCPDataSource;
|
import org.vibur.dbcp.ViburDBCPDataSource;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import static org.hibernate.cfg.AvailableSettings.AUTOCOMMIT;
|
||||||
import java.sql.SQLException;
|
import static org.hibernate.cfg.AvailableSettings.DRIVER;
|
||||||
import java.util.Map;
|
import static org.hibernate.cfg.AvailableSettings.ISOLATION;
|
||||||
import java.util.Properties;
|
import static org.hibernate.cfg.AvailableSettings.PASS;
|
||||||
|
import static org.hibernate.cfg.AvailableSettings.URL;
|
||||||
import static org.hibernate.cfg.AvailableSettings.*;
|
import static org.hibernate.cfg.AvailableSettings.USER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>ViburDBCP connection provider for Hibernate integration.
|
* <p>ViburDBCP connection provider for Hibernate integration.
|
||||||
|
@ -55,22 +61,12 @@ public class ViburDBCPConnectionProvider implements ConnectionProvider, Configur
|
||||||
|
|
||||||
private ViburDBCPDataSource dataSource = null;
|
private ViburDBCPDataSource dataSource = null;
|
||||||
|
|
||||||
private DatabaseConnectionInfo dbInfo;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configure(Map<String, Object> configurationValues) {
|
public void configure(Map<String, Object> configurationValues) {
|
||||||
ConnectionInfoLogger.INSTANCE.configureConnectionPool( "Vibur" );
|
ConnectionInfoLogger.INSTANCE.configureConnectionPool( "Vibur" );
|
||||||
|
|
||||||
dataSource = new ViburDBCPDataSource( transform( configurationValues ) );
|
dataSource = new ViburDBCPDataSource( transform( configurationValues ) );
|
||||||
dataSource.start();
|
dataSource.start();
|
||||||
|
|
||||||
dbInfo = new DatabaseConnectionInfoImpl()
|
|
||||||
.setDBUrl( dataSource.getJdbcUrl() )
|
|
||||||
.setDBDriverName( dataSource.getDriverClassName() )
|
|
||||||
.setDBAutoCommitMode( String.valueOf(dataSource.getDefaultAutoCommit()) )
|
|
||||||
.setDBIsolationLevel( dataSource.getDefaultTransactionIsolation() )
|
|
||||||
.setDBMinPoolSize( String.valueOf(dataSource.getPoolInitialSize()) )
|
|
||||||
.setDBMaxPoolSize( String.valueOf(dataSource.getPoolMaxSize()) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,8 +94,16 @@ public class ViburDBCPConnectionProvider implements ConnectionProvider, Configur
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DatabaseConnectionInfo getDatabaseConnectionInfo() {
|
public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
|
||||||
return dbInfo;
|
return new DatabaseConnectionInfoImpl(
|
||||||
|
dataSource.getJdbcUrl(),
|
||||||
|
dataSource.getDriverClassName(),
|
||||||
|
dialect.getVersion(),
|
||||||
|
String.valueOf( dataSource.getDefaultAutoCommit() ),
|
||||||
|
dataSource.getDefaultTransactionIsolation(),
|
||||||
|
dataSource.getPoolInitialSize(),
|
||||||
|
dataSource.getPoolMaxSize()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue