HHH-16310 Fix retrieval of JDBC metadata when MultiTenantConnectionProvider is set through the service registry builder

... as opposed to setting it through settings.
This commit is contained in:
Yoann Rodière 2023-03-15 10:33:26 +01:00
parent cc8f1f1020
commit 5bff5a383c
5 changed files with 28 additions and 5 deletions

View File

@ -21,6 +21,7 @@ import org.hibernate.boot.registry.StandardServiceInitiator;
import org.hibernate.boot.registry.selector.spi.StrategySelector;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.log.DeprecationLogger;
@ -93,7 +94,7 @@ public class ConnectionProviderInitiator implements StandardServiceInitiator<Con
@Override
public ConnectionProvider initiateService(Map<String, Object> configurationValues, ServiceRegistryImplementor registry) {
if ( configurationValues.containsKey( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER ) ) {
if ( registry.getService( MultiTenantConnectionProvider.class ) != null ) {
// nothing to do, but given the separate hierarchies have to handle this here.
return null;
}

View File

@ -157,6 +157,11 @@ public class ExtractedDatabaseMetaDataImpl implements ExtractedDatabaseMetaData
}
}
// For tests
public boolean isJdbcMetadataAccessible() {
return jdbcMetadataAccessible;
}
public static class Builder {
private final JdbcEnvironment jdbcEnvironment;
private final boolean jdbcMetadataIsAccessible;

View File

@ -147,7 +147,7 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
}
if ( useJdbcMetadata ) {
final JdbcConnectionAccess jdbcConnectionAccess = buildJdbcConnectionAccess( configurationValues, registry );
final JdbcConnectionAccess jdbcConnectionAccess = buildJdbcConnectionAccess( registry );
try {
final Connection connection = jdbcConnectionAccess.obtainConnection();
try {
@ -278,8 +278,9 @@ public class JdbcEnvironmentInitiator implements StandardServiceInitiator<JdbcEn
return o != null && ( !(o instanceof String) || !((String) o).isEmpty() );
}
private JdbcConnectionAccess buildJdbcConnectionAccess(Map<?,?> configValues, ServiceRegistryImplementor registry) {
if ( !configValues.containsKey( AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER ) ) {
private JdbcConnectionAccess buildJdbcConnectionAccess(ServiceRegistryImplementor registry) {
boolean multiTenancyEnabled = registry.getService( MultiTenantConnectionProvider.class ) != null;
if ( !multiTenancyEnabled ) {
ConnectionProvider connectionProvider = registry.getService( ConnectionProvider.class );
return new ConnectionProviderJdbcConnectionAccess( connectionProvider );
}

View File

@ -48,7 +48,7 @@ public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareServi
this.jdbcEnvironment = serviceRegistry.getService( JdbcEnvironment.class );
assert jdbcEnvironment != null : "JdbcEnvironment was not found";
this.multiTenancyEnabled = serviceRegistry.getService(MultiTenantConnectionProvider.class)!=null;
this.multiTenancyEnabled = serviceRegistry.getService( MultiTenantConnectionProvider.class ) != null;
final boolean showSQL = ConfigurationHelper.getBoolean( Environment.SHOW_SQL, configValues, false );
final boolean formatSQL = ConfigurationHelper.getBoolean( Environment.FORMAT_SQL, configValues, false );

View File

@ -17,6 +17,7 @@ import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.hibernate.engine.jdbc.env.internal.ExtractedDatabaseMetaDataImpl;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;
@ -27,14 +28,18 @@ import org.hibernate.tool.schema.internal.SchemaCreatorImpl;
import org.hibernate.tool.schema.internal.SchemaDropperImpl;
import org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.cache.CachingRegionFactory;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.orm.test.util.DdlTransactionIsolatorTestingImpl;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernateSessionBuilder;
/**
@ -62,6 +67,9 @@ public abstract class AbstractSchemaBasedMultiTenancyTest<T extends MultiTenantC
serviceRegistry = (ServiceRegistryImplementor) new StandardServiceRegistryBuilder()
.applySettings( settings )
// Make sure to continue configuring the MultiTenantConnectionProvider by adding a service,
// rather than by setting 'hibernate.multi_tenant_connection_provider':
// that's important to reproduce the regression we test in 'testJdbcMetadataAccessible'.
.addService( MultiTenantConnectionProvider.class, multiTenantConnectionProvider )
.build();
@ -141,6 +149,14 @@ public abstract class AbstractSchemaBasedMultiTenancyTest<T extends MultiTenantC
}
}
@Test
@TestForIssue(jiraKey = "HHH-16310")
public void testJdbcMetadataAccessible() {
assertThat( ( (ExtractedDatabaseMetaDataImpl) sessionFactory.getJdbcServices().getJdbcEnvironment()
.getExtractedDatabaseMetaData() ).isJdbcMetadataAccessible() )
.isTrue();
}
@Test
public void testBasicExpectedBehavior() {
Customer steve = doInHibernateSessionBuilder( this::jboss, session -> {