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 <[email protected]> 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() } }
