HHH-6054 introduce notion of a "root" tenant

This commit is contained in:
Gavin King 2021-09-13 13:39:04 +02:00 committed by Steve Ebersole
parent 47d0b1265f
commit 8f7e0c4c2f
3 changed files with 34 additions and 9 deletions

View File

@ -31,4 +31,13 @@ public interface CurrentTenantIdentifierResolver {
* @see org.hibernate.context.TenantIdentifierMismatchException
*/
public boolean validateExistingCurrentSessions();
/**
* Does the given tenant id represent a "root" tenant with access to all partitions.
* @param tenantId a tenant id produced by {@link #resolveCurrentTenantIdentifier()}
* @return true is this is root tenant
*/
public default boolean isRoot(String tenantId) {
return false;
}
}

View File

@ -51,6 +51,7 @@ import org.hibernate.UnknownProfileException;
import org.hibernate.UnresolvableObjectException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator;
@ -249,9 +250,13 @@ public class SessionImpl
throw new HibernateException( "SessionFactory configured for multi-tenancy, but no tenant identifier specified" );
}
else {
getLoadQueryInfluencers()
.enableFilter( TenantIdBinder.FILTER_NAME )
.setParameter( TenantIdBinder.PARAMETER_NAME, tenantIdentifier );
CurrentTenantIdentifierResolver resolver = factory.getCurrentTenantIdentifierResolver();
if ( resolver==null || !resolver.isRoot(tenantIdentifier) ) {
// turn on the filter, unless this is the "root" tenant with access to all partitions
getLoadQueryInfluencers()
.enableFilter( TenantIdBinder.FILTER_NAME )
.setParameter( TenantIdBinder.PARAMETER_NAME, tenantIdentifier );
}
}
}

View File

@ -9,6 +9,8 @@ package org.hibernate.tuple;
import org.hibernate.PropertyValueException;
import org.hibernate.Session;
import org.hibernate.annotations.TenantId;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.engine.spi.SessionFactoryImplementor;
/**
* Value generation implementation for {@link TenantId}.
@ -44,12 +46,21 @@ public class TenantIdGeneration implements AnnotationValueGeneration<TenantId>,
@Override
public Object generateValue(Session session, Object owner, Object currentValue) {
String identifier = session.getTenantIdentifier();
if ( currentValue != null && !currentValue.equals(identifier) ) {
throw new PropertyValueException(
"assigned tenant id differs from current tenant id: "
+ currentValue + "!=" + identifier,
entityName, propertyName
);
if ( currentValue != null ) {
CurrentTenantIdentifierResolver resolver =
((SessionFactoryImplementor) session.getSessionFactory())
.getCurrentTenantIdentifierResolver();
if ( resolver!=null && resolver.isRoot( session.getTenantIdentifier() ) ) {
// the "root" tenant is allowed to set the tenant id explicitly
return currentValue;
}
if ( !currentValue.equals(identifier) ) {
throw new PropertyValueException(
"assigned tenant id differs from current tenant id: "
+ currentValue + "!=" + identifier,
entityName, propertyName
);
}
}
return identifier;
}