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 * @see org.hibernate.context.TenantIdentifierMismatchException
*/ */
public boolean validateExistingCurrentSessions(); 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.UnresolvableObjectException;
import org.hibernate.cfg.AvailableSettings; import org.hibernate.cfg.AvailableSettings;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.engine.internal.StatefulPersistenceContext; import org.hibernate.engine.internal.StatefulPersistenceContext;
import org.hibernate.engine.jdbc.LobCreator; import org.hibernate.engine.jdbc.LobCreator;
import org.hibernate.engine.jdbc.NonContextualLobCreator; 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" ); throw new HibernateException( "SessionFactory configured for multi-tenancy, but no tenant identifier specified" );
} }
else { else {
getLoadQueryInfluencers() CurrentTenantIdentifierResolver resolver = factory.getCurrentTenantIdentifierResolver();
.enableFilter( TenantIdBinder.FILTER_NAME ) if ( resolver==null || !resolver.isRoot(tenantIdentifier) ) {
.setParameter( TenantIdBinder.PARAMETER_NAME, 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.PropertyValueException;
import org.hibernate.Session; import org.hibernate.Session;
import org.hibernate.annotations.TenantId; import org.hibernate.annotations.TenantId;
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
import org.hibernate.engine.spi.SessionFactoryImplementor;
/** /**
* Value generation implementation for {@link TenantId}. * Value generation implementation for {@link TenantId}.
@ -44,12 +46,21 @@ public class TenantIdGeneration implements AnnotationValueGeneration<TenantId>,
@Override @Override
public Object generateValue(Session session, Object owner, Object currentValue) { public Object generateValue(Session session, Object owner, Object currentValue) {
String identifier = session.getTenantIdentifier(); String identifier = session.getTenantIdentifier();
if ( currentValue != null && !currentValue.equals(identifier) ) { if ( currentValue != null ) {
throw new PropertyValueException( CurrentTenantIdentifierResolver resolver =
"assigned tenant id differs from current tenant id: " ((SessionFactoryImplementor) session.getSessionFactory())
+ currentValue + "!=" + identifier, .getCurrentTenantIdentifierResolver();
entityName, propertyName 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; return identifier;
} }