You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/03/01 03:15:09 UTC
(grails-core) 05/06: refactor more MultiTenantFilterBinder
This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch 8.0.x-hibernate7
in repository https://gitbox.apache.org/repos/asf/grails-core.git
commit 202a8cb439d0f85e0e8fe467143859a5b8aaf814
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sat Feb 28 15:21:23 2026 -0600
refactor more MultiTenantFilterBinder
---
.../cfg/domainbinding/binder/RootBinder.java | 2 +-
.../cfg/domainbinding/binder/SubClassBinder.java | 2 +-
.../util/MultiTenantFilterBinder.java | 27 +++++++++++----
.../util/MultiTenantFilterDefinitionBinder.java | 18 +++++-----
.../cfg/domainbinding/binder/RootBinderSpec.groovy | 4 +--
.../domainbinding/binder/SubClassBinderSpec.groovy | 4 +--
.../util/MultiTenantFilterBinderSpec.groovy | 8 ++---
.../MultiTenantFilterDefinitionBinderSpec.groovy | 38 +++++-----------------
8 files changed, 47 insertions(+), 56 deletions(-)
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
index 7d45d5a207..835694a45b 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinder.java
@@ -83,7 +83,7 @@ public class RootBinder {
// bind the sub classes
children.forEach(sub -> subClassBinder.bindSubClass(sub, root, mappings, m));
- multiTenantFilterBinder.addMultiTenantFilterIfNecessary(entity, root);
+ multiTenantFilterBinder.bind(entity, root);
mappings.addEntityBinding(root);
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
index 8b416c6bd9..fd4480d896 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinder.java
@@ -67,7 +67,7 @@ public class SubClassBinder {
parent.addSubclass(subClass);
mappings.addEntityBinding(subClass);
- multiTenantFilterBinder.addMultiTenantFilterIfNecessary(sub, subClass);
+ multiTenantFilterBinder.bind(sub, subClass);
Collection<GrailsHibernatePersistentEntity> children = sub.getChildEntities(dataSourceName);
if (!children.isEmpty()) {
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
index 412e9c18df..e43f08202d 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
@@ -19,12 +19,14 @@
package org.grails.orm.hibernate.cfg.domainbinding.util;
import jakarta.annotation.Nonnull;
+import jakarta.annotation.Nullable;
import java.util.Collections;
import java.util.Optional;
import org.grails.datastore.mapping.model.config.GormProperties;
import org.grails.datastore.mapping.model.types.TenantId;
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity;
import org.hibernate.boot.spi.InFlightMetadataCollector;
+import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
@@ -53,27 +55,38 @@ public class MultiTenantFilterBinder {
}
/**
- * Adds a multi-tenant filter to the given persistent class if necessary.
+ * Binds a multi-tenant filter to the given persistent class if necessary.
*
* @param entity The target persistent entity
* @param persistentClass The persistent class to add the filter to
+ * @return The filter definition applied, or null if none
*/
- public void addMultiTenantFilterIfNecessary(
+ @Nullable
+ public FilterDefinition bind(
@Nonnull GrailsHibernatePersistentEntity entity, @Nonnull PersistentClass persistentClass) {
if (!entity.isMultiTenant()) {
- return;
+ return null;
}
- Optional.ofNullable(entity.getTenantId())
+ return Optional.ofNullable(entity.getTenantId())
.map(TenantId::getName)
.map(name -> grailsPropertyResolver.getProperty(persistentClass, name))
- .ifPresent(
+ .map(
property -> {
var filterName = GormProperties.TENANT_IDENTITY;
- filterDefinitionBinder.ensureGlobalFilterDefinition(mappings, filterName, property);
+ FilterDefinition filterDefinition = mappings.getFilterDefinition(filterName);
+ if (filterDefinition == null) {
+ filterDefinition = filterDefinitionBinder.create(filterName, property).orElse(null);
+ if (filterDefinition != null) {
+ mappings.addFilterDefinition(filterDefinition);
+ }
+ }
+
applyFilterToPersistentClass(entity, persistentClass, filterName, property);
- });
+ return filterDefinition;
+ })
+ .orElse(null);
}
private void applyFilterToPersistentClass(
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinder.java
index 51d21f8409..6e86d6507c 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinder.java
@@ -20,7 +20,7 @@ package org.grails.orm.hibernate.cfg.domainbinding.util;
import jakarta.annotation.Nonnull;
import java.util.Collections;
-import org.hibernate.boot.spi.InFlightMetadataCollector;
+import java.util.Optional;
import org.hibernate.engine.spi.FilterDefinition;
import org.hibernate.mapping.BasicValue;
import org.hibernate.mapping.Property;
@@ -34,24 +34,22 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
public class MultiTenantFilterDefinitionBinder {
/**
- * Ensures that a global filter definition exists for the given filter name.
+ * Creates a global filter definition for the given filter name.
*
- * @param mappings The in-flight metadata collector
* @param filterName The name of the filter
* @param property The property to get the type from
+ * @return The FilterDefinition Optional
*/
- public void ensureGlobalFilterDefinition(
- @Nonnull InFlightMetadataCollector mappings,
- @Nonnull String filterName,
- @Nonnull Property property) {
- if (mappings.getFilterDefinition(filterName) == null
- && property.getValue() instanceof BasicValue basicValue) {
+ @Nonnull
+ public Optional<FilterDefinition> create(@Nonnull String filterName, @Nonnull Property property) {
+ if (property.getValue() instanceof BasicValue basicValue) {
JdbcMapping jdbcMapping = basicValue.resolve().getJdbcMapping();
- mappings.addFilterDefinition(
+ return Optional.of(
new FilterDefinition(
filterName,
null, // No default condition; let classes specify their own
Collections.singletonMap(filterName, jdbcMapping)));
}
+ return Optional.empty();
}
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
index 567ca9b235..144cdcf532 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
@@ -57,7 +57,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
1 * rootPersistentClassCommonValuesBinder.bindRootPersistentClassCommonValues(entity, [], mappings) >> rootClass
0 * discriminatorPropertyBinder.bindDiscriminatorProperty(_)
0 * subClassBinder.bindSubClass(_, _, _, _)
- 1 * multiTenantFilterBinder.addMultiTenantFilterIfNecessary(entity, rootClass)
+ 1 * multiTenantFilterBinder.bind(entity, rootClass)
mappings.getEntityBinding("Parent") == rootClass
}
@@ -84,7 +84,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
1 * rootPersistentClassCommonValuesBinder.bindRootPersistentClassCommonValues(entity, [childEntity], mappings) >> rootClass
1 * discriminatorPropertyBinder.bindDiscriminatorProperty(rootClass)
1 * subClassBinder.bindSubClass(childEntity, rootClass, mappings, mapping)
- 1 * multiTenantFilterBinder.addMultiTenantFilterIfNecessary(entity, rootClass)
+ 1 * multiTenantFilterBinder.bind(entity, rootClass)
mappings.getEntityBinding("Parent") == rootClass
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
index fd81f6148c..7d5378055f 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
@@ -55,7 +55,7 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
then:
1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings, mapping) >> subClass
- 1 * multiTenantFilterBinder.addMultiTenantFilterIfNecessary(subEntity, subClass)
+ 1 * multiTenantFilterBinder.bind(subEntity, subClass)
rootClass.getSubclasses().contains(subClass)
mappings.getEntityBinding(subClass.getEntityName()) == subClass
}
@@ -88,7 +88,7 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
then:
1 * subclassMappingBinder.createSubclassMapping(subEntity, rootClass, mappings, mapping) >> subClass
1 * subclassMappingBinder.createSubclassMapping(grandChildEntity, subClass, mappings, mapping) >> grandChildSubClass
- 2 * multiTenantFilterBinder.addMultiTenantFilterIfNecessary(_, _)
+ 2 * multiTenantFilterBinder.bind(_, _)
rootClass.getSubclasses().contains(subClass)
subClass.getSubclasses().contains(grandChildSubClass)
}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinderSpec.groovy
index 28008119fe..99f213eca6 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinderSpec.groovy
@@ -58,7 +58,7 @@ class MultiTenantFilterBinderSpec extends HibernateGormDatastoreSpec {
entity.getMultiTenantFilterCondition(fetcher) >> "tenant_id = :tenantId"
when:
- filterBinder.addMultiTenantFilterIfNecessary(entity, persistentClass)
+ filterBinder.bind(entity, persistentClass)
then:
1 * mockCollector.addFilterDefinition(_ as FilterDefinition)
@@ -93,7 +93,7 @@ class MultiTenantFilterBinderSpec extends HibernateGormDatastoreSpec {
mockCollector.getFilterDefinition(_) >> Mock(FilterDefinition)
when:
- filterBinder.addMultiTenantFilterIfNecessary(entity, persistentClass)
+ filterBinder.bind(entity, persistentClass)
then:
!persistentClass.getFilters().any { it.getName() == GormProperties.TENANT_IDENTITY }
@@ -130,7 +130,7 @@ class MultiTenantFilterBinderSpec extends HibernateGormDatastoreSpec {
mockCollector.getFilterDefinition(_) >> Mock(FilterDefinition)
when:
- filterBinder.addMultiTenantFilterIfNecessary(entity, persistentClass)
+ filterBinder.bind(entity, persistentClass)
then:
!persistentClass.getFilters().any { it.getName() == GormProperties.TENANT_IDENTITY }
@@ -165,7 +165,7 @@ class MultiTenantFilterBinderSpec extends HibernateGormDatastoreSpec {
entity.getMultiTenantFilterCondition(fetcher) >> "tenant_id = :tenantId"
when:
- filterBinder.addMultiTenantFilterIfNecessary(entity, persistentClass)
+ filterBinder.bind(entity, persistentClass)
then:
persistentClass.getFilters().any { it.getName() == GormProperties.TENANT_IDENTITY && it.getCondition() == "tenant_id = :tenantId" }
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinderSpec.groovy
index 9703553b27..a270d15f9c 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterDefinitionBinderSpec.groovy
@@ -2,12 +2,10 @@ package org.grails.orm.hibernate.cfg.domainbinding.util
import grails.gorm.specs.HibernateGormDatastoreSpec
import org.grails.datastore.mapping.model.config.GormProperties
-import org.hibernate.boot.spi.InFlightMetadataCollector
import org.hibernate.mapping.BasicValue
import org.hibernate.mapping.Property
import org.hibernate.mapping.Table
import org.hibernate.engine.spi.FilterDefinition
-import org.hibernate.metamodel.mapping.JdbcMapping
/**
* Tests for MultiTenantFilterDefinitionBinder.
@@ -15,9 +13,8 @@ import org.hibernate.metamodel.mapping.JdbcMapping
class MultiTenantFilterDefinitionBinderSpec extends HibernateGormDatastoreSpec {
MultiTenantFilterDefinitionBinder filterDefinitionBinder = new MultiTenantFilterDefinitionBinder()
- InFlightMetadataCollector mockCollector = GroovyMock(InFlightMetadataCollector)
- void "test ensureGlobalFilterDefinition adds filter definition if not present"() {
+ void "test create adds filter definition"() {
given:
def buildingContext = getGrailsDomainBinder().getMetadataBuildingContext()
def property = new Property()
@@ -31,32 +28,16 @@ class MultiTenantFilterDefinitionBinderSpec extends HibernateGormDatastoreSpec {
def filterName = GormProperties.TENANT_IDENTITY
when:
- filterDefinitionBinder.ensureGlobalFilterDefinition(mockCollector, filterName, property)
+ Optional<FilterDefinition> filterDefinition = filterDefinitionBinder.create(filterName, property)
then:
- 1 * mockCollector.getFilterDefinition(filterName) >> null
- 1 * mockCollector.addFilterDefinition({ FilterDefinition fd ->
- fd.getFilterName() == filterName &&
- fd.getDefaultFilterCondition() == null &&
- fd.getParameterNames().contains(filterName)
- })
+ filterDefinition.isPresent()
+ filterDefinition.get().getFilterName() == filterName
+ filterDefinition.get().getDefaultFilterCondition() == null
+ filterDefinition.get().getParameterNames().contains(filterName)
}
- void "test ensureGlobalFilterDefinition does not add if already present"() {
- given:
- def property = new Property()
- def filterName = GormProperties.TENANT_IDENTITY
- def existingFilter = Mock(FilterDefinition)
-
- when:
- filterDefinitionBinder.ensureGlobalFilterDefinition(mockCollector, filterName, property)
-
- then:
- 1 * mockCollector.getFilterDefinition(filterName) >> existingFilter
- 0 * mockCollector.addFilterDefinition(_)
- }
-
- void "test ensureGlobalFilterDefinition does not add if property value is not BasicValue"() {
+ void "test create returns empty if property value is not BasicValue"() {
given:
def property = new Property()
def filterName = GormProperties.TENANT_IDENTITY
@@ -65,10 +46,9 @@ class MultiTenantFilterDefinitionBinderSpec extends HibernateGormDatastoreSpec {
property.setValue(null)
when:
- filterDefinitionBinder.ensureGlobalFilterDefinition(mockCollector, filterName, property)
+ Optional<FilterDefinition> filterDefinition = filterDefinitionBinder.create(filterName, property)
then:
- 1 * mockCollector.getFilterDefinition(filterName) >> null
- 0 * mockCollector.addFilterDefinition(_)
+ !filterDefinition.isPresent()
}
}