HHH-14386 Fails to boot if provided CurrentTenantIdentifierResolver is unable to operate during bootstrap

This commit is contained in:
Sanne Grinovero 2021-02-01 21:31:36 +00:00
parent 0e75b4f3b5
commit 15d418c332
2 changed files with 34 additions and 13 deletions

View File

@ -379,8 +379,8 @@ public void sessionFactoryClosed(SessionFactory factory) {
fetchProfiles.put( fetchProfile.getName(), fetchProfile );
}
this.defaultSessionOpenOptions = withOptions();
this.temporarySessionOpenOptions = buildTemporarySessionOpenOptions();
this.defaultSessionOpenOptions = createDefaultSessionOpenOptionsIfPossible();
this.temporarySessionOpenOptions = this.defaultSessionOpenOptions == null ? null : buildTemporarySessionOpenOptions();
this.fastSessionServices = new FastSessionServices( this );
this.observer.sessionFactoryCreated( this );
@ -407,6 +407,17 @@ public void sessionFactoryClosed(SessionFactory factory) {
}
}
private SessionBuilder createDefaultSessionOpenOptionsIfPossible() {
final CurrentTenantIdentifierResolver currentTenantIdentifierResolver = getCurrentTenantIdentifierResolver();
if ( currentTenantIdentifierResolver == null ) {
return withOptions();
}
else {
//Don't store a default SessionBuilder when a CurrentTenantIdentifierResolver is provided
return null;
}
}
private SessionBuilder buildTemporarySessionOpenOptions() {
return withOptions()
.autoClose( false )
@ -454,25 +465,23 @@ private JdbcConnectionAccess buildLocalConnectionAccess() {
}
public Session openSession() throws HibernateException {
final CurrentTenantIdentifierResolver currentTenantIdentifierResolver = getCurrentTenantIdentifierResolver();
//We can only reuse the defaultSessionOpenOptions as a constant when there is no TenantIdentifierResolver
if ( currentTenantIdentifierResolver != null ) {
return this.withOptions().openSession();
//The defaultSessionOpenOptions can't be used in some cases; for example when using a TenantIdentifierResolver.
if ( this.defaultSessionOpenOptions != null ) {
return this.defaultSessionOpenOptions.openSession();
}
else {
return this.defaultSessionOpenOptions.openSession();
return this.withOptions().openSession();
}
}
public Session openTemporarySession() throws HibernateException {
final CurrentTenantIdentifierResolver currentTenantIdentifierResolver = getCurrentTenantIdentifierResolver();
//We can only reuse the defaultSessionOpenOptions as a constant when there is no TenantIdentifierResolver
if ( currentTenantIdentifierResolver != null ) {
return buildTemporarySessionOpenOptions()
.openSession();
//The temporarySessionOpenOptions can't be used in some cases; for example when using a TenantIdentifierResolver.
if ( this.temporarySessionOpenOptions != null ) {
return this.temporarySessionOpenOptions.openSession();
}
else {
return this.temporarySessionOpenOptions.openSession();
return buildTemporarySessionOpenOptions()
.openSession();
}
}

View File

@ -9,6 +9,7 @@
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import org.hibernate.MultiTenancyStrategy;
@ -108,6 +109,7 @@ public void setUp() {
final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
sessionFactory = (SessionFactoryImplementor) sfb.build();
currentTenantResolver.setHibernateBooted();
}
@After
@ -181,9 +183,19 @@ public void testDiscriminator() {
private static class TestCurrentTenantIdentifierResolver implements CurrentTenantIdentifierResolver {
private String currentTenantIdentifier;
private final AtomicBoolean postBoot = new AtomicBoolean(false);
public void setHibernateBooted() {
postBoot.set( true );
}
@Override
public String resolveCurrentTenantIdentifier() {
if ( postBoot.get() == false ) {
//Check to prevent any optimisation which might want to cache the tenantId too early during bootstrap:
//it's a common use case to want to provide the tenantId, for example, via a ThreadLocal.
throw new IllegalStateException( "Not booted yet: illegal to try reading the tenant Id at this point!" );
}
return currentTenantIdentifier;
}