From 7b308d048f3ef36615be1a51b542b370c37f5fc3 Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Wed, 11 Jan 2023 17:46:54 +0100 Subject: [PATCH] HHH-15902 @OneToMany relationship with @Where on child table generates wrong sql --- .../java/org/hibernate/annotations/Where.java | 4 +- .../org/hibernate/cfg/AvailableSettings.java | 4 +- .../ast/internal/LoaderSelectBuilder.java | 80 +++++++++++-------- 3 files changed, 51 insertions(+), 37 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java index 30cfa046da..d73ff2b2e8 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java @@ -48,7 +48,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * List<Document> documents; * *

- * By default, {@code @Where} restrictions declared for an entity are not + * By default, {@code @Where} restrictions declared for an entity are * applied when loading a collection of that entity type. This behavior is * controlled by: *

    @@ -84,7 +84,7 @@ public @interface Where { *

    * By default, the restriction is not applied unless the property * {@value org.hibernate.cfg.AvailableSettings#USE_ENTITY_WHERE_CLAUSE_FOR_COLLECTIONS} - * is explicitly enabled. + * is explicitly disabled. * * @return {@code true} if the restriction should be applied even * if the configuration property is not enabled diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 379da34a28..4d7f5d5031 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -2041,8 +2041,8 @@ public interface AvailableSettings { * {@link jakarta.persistence.ManyToMany many-to-many} association whose target * type defines the restriction. *

    - * By default, the restriction is not applied. When this setting is enabled, the - * restriction is applied. + * By default, the restriction is applied. When this setting is disabled, the + * restriction is not applied. *

    * The setting has no effect on a collection of {@link jakarta.persistence.Embeddable * embeddable} values containing a {@link jakarta.persistence.ManyToOne many-to-one} diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java index 1cb6385f68..3b7a8b57eb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderSelectBuilder.java @@ -576,41 +576,55 @@ public class LoaderSelectBuilder { TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping, SqlAstCreationState astCreationState) { - pluralAttributeMapping.applyBaseRestrictions( - querySpec::applyPredicate, - tableGroup, - true, - loadQueryInfluencers.getEnabledFilters(), - null, - astCreationState - ); + final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent(); + if ( parentNavigablePath == null ) { + pluralAttributeMapping.applyBaseRestrictions( + querySpec::applyPredicate, + tableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + null, + astCreationState + ); + pluralAttributeMapping.applyBaseManyToManyRestrictions( + querySpec::applyPredicate, + tableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + null, + astCreationState + ); + } + else { + final TableGroup parentTableGroup = astCreationState.getFromClauseAccess().getTableGroup( + parentNavigablePath ); + TableGroupJoin pluralTableGroupJoin = null; + for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { + if ( nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath() ) { + pluralTableGroupJoin = nestedTableGroupJoin; + break; + } + } - pluralAttributeMapping.applyBaseManyToManyRestrictions( - (filterPredicate) -> { - final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent(); - if ( parentNavigablePath == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - final TableGroup parentTableGroup = astCreationState.getFromClauseAccess().getTableGroup( parentNavigablePath ); - TableGroupJoin pluralTableGroupJoin = null; - for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { - if ( nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath() ) { - pluralTableGroupJoin = nestedTableGroupJoin; - break; - } - } + assert pluralTableGroupJoin != null; - assert pluralTableGroupJoin != null; - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } - }, - tableGroup, - true, - loadQueryInfluencers.getEnabledFilters(), - null, - astCreationState - ); + pluralAttributeMapping.applyBaseRestrictions( + pluralTableGroupJoin::applyPredicate, + tableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + null, + astCreationState + ); + pluralAttributeMapping.applyBaseManyToManyRestrictions( + pluralTableGroupJoin::applyPredicate, + tableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + null, + astCreationState + ); + } } private void applyFiltering(