diff --git a/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java index 93b192bf6e..f45752ed3a 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/FilterHelper.java @@ -7,25 +7,24 @@ package org.hibernate.internal; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.hibernate.Filter; import org.hibernate.MappingException; -import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.mapping.JdbcMapping; -import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.persister.entity.Joinable; import org.hibernate.sql.Template; -import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.predicate.FilterPredicate; +import org.hibernate.sql.ast.tree.predicate.Predicate; +import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.type.Type; import static org.hibernate.internal.util.StringHelper.safeInterning; @@ -39,12 +38,13 @@ import static org.hibernate.internal.util.StringHelper.safeInterning; */ public class FilterHelper { - private static final Pattern FILTER_PARAMETER_PATTERN = Pattern.compile( ":(\\S+)\\.(\\w+)" ); + private static final Pattern FILTER_PARAMETER_PATTERN = Pattern.compile( ":(\\S+)(\\w+)" ); private final String[] filterNames; private final String[] filterConditions; private final boolean[] filterAutoAliasFlags; private final Map[] filterAliasTableMaps; + private final List[] parameterNames; /** * The map of defined filters. This is expected to be in format @@ -56,10 +56,13 @@ public class FilterHelper { */ public FilterHelper(List filters, SessionFactoryImplementor factory) { int filterCount = filters.size(); + filterNames = new String[filterCount]; filterConditions = new String[filterCount]; filterAutoAliasFlags = new boolean[filterCount]; filterAliasTableMaps = new Map[filterCount]; + parameterNames = new List[filterCount]; + filterCount = 0; for ( final FilterConfiguration filter : filters ) { filterAutoAliasFlags[filterCount] = false; @@ -80,13 +83,17 @@ public class FilterHelper { filterAutoAliasFlags[filterCount] = true; } - filterConditions[filterCount] = safeInterning( - StringHelper.replace( - filterConditions[filterCount], - ":", - ":" + filterNames[filterCount] + "." - ) - ); + final Matcher matcher = FILTER_PARAMETER_PATTERN.matcher( filterConditions[filterCount] ); + String copy = filterConditions[filterCount]; + final List filterParamNames = new ArrayList<>(); + parameterNames[filterCount] = filterParamNames; + while( matcher.find() ) { + final String parameterLabel = filterConditions[filterCount].substring( matcher.start() + 1, matcher.end() ); + filterParamNames.add( parameterLabel ); + copy = copy.replaceAll( ":" + parameterLabel, ":" + filterNames[filterCount] + "." + parameterLabel ); + } + filterConditions[filterCount] = safeInterning( copy ); + filterCount++; } } @@ -154,113 +161,85 @@ public class FilterHelper { } } - public static FilterPredicate createFilterPredicate( - LoadQueryInfluencers loadQueryInfluencers, - Joinable joinable, - TableGroup rootTableGroup) { - return createFilterPredicate( loadQueryInfluencers, joinable, rootTableGroup, true ); - } - - public static FilterPredicate createFilterPredicate( - Map enabledFilters, - Joinable joinable, - TableGroup rootTableGroup) { - return createFilterPredicate( enabledFilters, joinable, rootTableGroup, true ); - } - - public static FilterPredicate createFilterPredicate( - Map enabledFilters, - Joinable joinable, - TableGroup rootTableGroup, - boolean useIdentificationVariable) { - final String filterFragment = joinable.filterFragment( - rootTableGroup, - enabledFilters, - Collections.emptySet(), - useIdentificationVariable - ); - if ( StringHelper.isNotEmpty( filterFragment ) ) { - return doCreateFilterPredicate( filterFragment, enabledFilters ); - } - else { - return null; - } - - } - - public static FilterPredicate createFilterPredicate( - LoadQueryInfluencers loadQueryInfluencers, - Joinable joinable, - TableGroup rootTableGroup, - boolean useIdentificationVariable) { - final String filterFragment = joinable.filterFragment( - rootTableGroup, - loadQueryInfluencers.getEnabledFilters(), - Collections.emptySet(), - useIdentificationVariable - ); - if ( StringHelper.isNotEmpty( filterFragment ) ) { - return doCreateFilterPredicate( filterFragment, loadQueryInfluencers.getEnabledFilters() ); - } - else { - return null; + public void applyFilters( + FilterAliasGenerator aliasGenerator, + Map enabledFilters, + Consumer predicateConsumer) { + final FilterPredicate predicate = generateFilterPredicate( aliasGenerator, enabledFilters ); + if ( predicate != null ) { + predicateConsumer.accept( predicate ); } } - public static FilterPredicate createManyToManyFilterPredicate(LoadQueryInfluencers loadQueryInfluencers, CollectionPersister collectionPersister, TableGroup tableGroup) { - assert collectionPersister.isManyToMany(); - final String filterFragment = collectionPersister.getManyToManyFilterFragment( tableGroup, loadQueryInfluencers.getEnabledFilters() ); - if ( StringHelper.isNotEmpty( filterFragment ) ) { - return doCreateFilterPredicate( filterFragment, loadQueryInfluencers.getEnabledFilters() ); - } - else { - return null; + public void applyFilters( + QuerySpec querySpec, + FilterAliasGenerator aliasGenerator, + Map enabledFilters) { + final FilterPredicate predicate = generateFilterPredicate( aliasGenerator, enabledFilters ); + if ( predicate != null ) { + querySpec.applyPredicate( predicate ); } } - public static FilterPredicate doCreateFilterPredicate(String filterFragment, Map enabledFilters) { - final Matcher matcher = FILTER_PARAMETER_PATTERN.matcher( filterFragment ); - final StringBuilder sb = new StringBuilder(); - int pos = 0; - final List parameters = new ArrayList<>( matcher.groupCount() ); - while( matcher.find() ) { - sb.append( filterFragment, pos, matcher.start() ); - pos = matcher.end(); - sb.append( "?" ); - final String filterName = matcher.group( 1 ); - final String parameterName = matcher.group( 2 ); + public FilterPredicate generateFilterPredicate(FilterAliasGenerator aliasGenerator, Map enabledFilters) { + final FilterPredicate filterPredicate = new FilterPredicate(); + + for ( int i = 0, max = filterNames.length; i < max; i++ ) { + final String filterName = filterNames[i]; final FilterImpl enabledFilter = (FilterImpl) enabledFilters.get( filterName ); - if ( enabledFilter == null ) { - throw new MappingException( String.format( "unknown filter [%s]", filterName ) ); - } - final Type parameterType = enabledFilter.getFilterDefinition().getParameterType( parameterName ); - if ( ! (parameterType instanceof JdbcMapping ) ) { - throw new MappingException( String.format( "parameter [%s] for filter [%s] is not of JdbcMapping type", parameterName, filterName ) ); - } - final JdbcMapping jdbcMapping = (JdbcMapping) parameterType; - final Object parameterValue = enabledFilter.getParameter( parameterName ); - if ( parameterValue == null ) { - throw new MappingException( String.format( "unknown parameter [%s] for filter [%s]", parameterName, filterName ) ); - } - if ( parameterValue instanceof Iterable && !jdbcMapping.getJavaTypeDescriptor().isInstance( parameterValue ) ) { - final Iterator iterator = ( (Iterable) parameterValue ).iterator(); - if ( iterator.hasNext() ) { - parameters.add( new FilterJdbcParameter( jdbcMapping, iterator.next() ) ); - while ( iterator.hasNext() ) { - sb.append( ",?" ); - parameters.add( new FilterJdbcParameter( jdbcMapping, iterator.next() ) ); + if ( enabledFilter != null ) { + String condition = render( aliasGenerator, i ); + + final List filterParameterNames = parameterNames[i]; + for ( int paramPos = 0; paramPos < filterParameterNames.size(); paramPos++ ) { + final String parameterName = filterParameterNames.get( paramPos ); + + final Type parameterType = enabledFilter.getFilterDefinition().getParameterType( parameterName ); + if ( ! (parameterType instanceof JdbcMapping) ) { + throw new MappingException( String.format( "parameter [%s] for filter [%s] is not of JdbcMapping type", parameterName, filterName ) ); } + + final JdbcMapping jdbcMapping = (JdbcMapping) parameterType; + final Object parameterValue = enabledFilter.getParameter( parameterName ); + if ( parameterValue == null ) { + throw new MappingException( String.format( "unknown parameter [%s] for filter [%s]", parameterName, filterName ) ); + } + + final StringBuilder paramMarkers = new StringBuilder( "?" ); + if ( parameterValue instanceof Iterable + && !jdbcMapping.getJavaTypeDescriptor().isInstance( parameterValue ) ) { + final Iterator iterator = ( (Iterable) parameterValue ).iterator(); + if ( iterator.hasNext() ) { + final Object value = iterator.next(); + final FilterJdbcParameter jdbcParameter = new FilterJdbcParameter( jdbcMapping, value ); + filterPredicate.applyParameter( jdbcParameter ); + + while ( iterator.hasNext() ) { + paramMarkers.append( ",?" ); + filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, iterator.next() ) ); + } + } + else { + // We need a dummy value if the list is empty + filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, null ) ); + } + } + else { + filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, parameterValue ) ); + } + + final String marker = ":" + filterNames[ i ] + "." + parameterName; + condition = condition.replaceAll( marker, paramMarkers.toString() ); } - else { - // We need a dummy value if the list is empty - parameters.add( new FilterJdbcParameter( jdbcMapping, null ) ); - } - } - else { - parameters.add( new FilterJdbcParameter( jdbcMapping, parameterValue ) ); + + filterPredicate.applyFragment( condition ); } } - sb.append( filterFragment, pos, filterFragment.length() ); - return new FilterPredicate( sb.toString(), parameters ); + + if ( filterPredicate.isEmpty() ) { + return null; + } + + return filterPredicate; } } 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 7a30c8163d..4179b9fe52 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 @@ -40,6 +40,8 @@ import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.NaturalIdMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.metamodel.mapping.Restrictable; +import org.hibernate.metamodel.mapping.Restrictable.RestrictionPredicatePartType; import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping; import org.hibernate.metamodel.mapping.internal.NonAggregatedIdentifierMappingImpl; import org.hibernate.metamodel.mapping.internal.SimpleForeignKeyDescriptor; @@ -363,12 +365,18 @@ public class LoaderSelectBuilder { } private SelectStatement generateSelect() { + final Restrictable restrictable; if ( loadable instanceof PluralAttributeMapping ) { final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) loadable; + restrictable = (Restrictable) pluralAttributeMapping.getCollectionDescriptor(); if ( pluralAttributeMapping.getMappedType().getCollectionSemantics() instanceof BagSemantics ) { currentBagRole = pluralAttributeMapping.getNavigableRole().getNavigableName(); } } + else { + restrictable = (Restrictable) loadable; + } + final NavigablePath rootNavigablePath = new NavigablePath( loadable.getRootPathName() ); final QuerySpec rootQuerySpec = new QuerySpec( true ); @@ -393,6 +401,15 @@ public class LoaderSelectBuilder { creationContext ); + restrictable.applyRestrictions( + (predicate, partType, sourceType) -> rootQuerySpec.applyPredicate( predicate ), + rootTableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + Collections.emptySet(), + sqlAstCreationState.getFromClauseAccess() + ); + rootQuerySpec.getFromClause().addRoot( rootTableGroup ); sqlAstCreationState.getFromClauseAccess().registerTableGroup( rootNavigablePath, rootTableGroup ); registerPluralTableGroupParts( sqlAstCreationState.getFromClauseAccess(), rootTableGroup ); @@ -473,12 +490,8 @@ public class LoaderSelectBuilder { if ( loadable instanceof PluralAttributeMapping ) { final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) loadable; - applyFiltering( rootQuerySpec, rootTableGroup, pluralAttributeMapping, sqlAstCreationState.getFromClauseAccess() ); applyOrdering( rootTableGroup, pluralAttributeMapping ); } - else if ( loadable instanceof Joinable ) { - applyFiltering( rootQuerySpec, rootTableGroup, (Joinable) loadable, sqlAstCreationState.getFromClauseAccess() ); - } if ( orderByFragments != null ) { orderByFragments.forEach( @@ -588,7 +601,30 @@ public class LoaderSelectBuilder { final CollectionPersister collectionPersister = pluralAttributeMapping.getCollectionDescriptor(); final Joinable joinable = collectionPersister.getCollectionType().getAssociatedJoinable( creationContext.getSessionFactory() ); joinable.applyRestrictions( - querySpec, + (predicate,partType,sourceType) -> { + if ( partType == RestrictionPredicatePartType.COLLECTION ) { + querySpec.applyPredicate( predicate ); + } + else if ( partType == RestrictionPredicatePartType.MANY_TO_MANY ) { + final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent(); + if ( parentNavigablePath == null ) { + querySpec.applyPredicate( predicate ); + } + else { + final TableGroup parentTableGroup = fromClauseAccess.getTableGroup( parentNavigablePath ); + TableGroupJoin pluralTableGroupJoin = null; + for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { + if ( nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath() ) { + pluralTableGroupJoin = nestedTableGroupJoin; + break; + } + } + + assert pluralTableGroupJoin != null; + pluralTableGroupJoin.applyPredicate( predicate ); + } + } + }, tableGroup, true, loadQueryInfluencers.getEnabledFilters(), diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java index e4ad74ca13..21a7be1d8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/EntityMappingType.java @@ -14,9 +14,11 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; +import org.hibernate.Filter; import org.hibernate.NotYetImplementedFor6Exception; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.FilterAliasGenerator; import org.hibernate.loader.ast.spi.Loadable; import org.hibernate.loader.ast.spi.MultiNaturalIdLoader; import org.hibernate.loader.ast.spi.NaturalIdLoader; @@ -37,6 +39,7 @@ import org.hibernate.sql.ast.spi.SqlSelection; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableReference; import org.hibernate.sql.ast.tree.from.TableReferenceJoin; +import org.hibernate.sql.ast.tree.predicate.FilterPredicate; import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.DomainResultAssembler; @@ -493,4 +496,10 @@ public interface EntityMappingType extends ManagedMappingType, EntityValuedModel default int getNumberOfFetchables() { return getEntityPersister().getNumberOfFetchables(); } + + FilterPredicate generateFilterPredicate( + TableGroup tableGroup, + boolean useQualifier, + Set treatAsDeclarations, + Map enabledFilters); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Restrictable.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Restrictable.java new file mode 100644 index 0000000000..96a8602208 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/Restrictable.java @@ -0,0 +1,72 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.metamodel.mapping; + +import java.util.Map; +import java.util.Set; + +import org.hibernate.Filter; +import org.hibernate.persister.entity.Joinable; +import org.hibernate.sql.ast.spi.FromClauseAccess; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.predicate.Predicate; +import org.hibernate.sql.ast.tree.select.QuerySpec; + +/** + * Things that can have {@link org.hibernate.annotations.Where} + * and {@link org.hibernate.annotations.Filter} applied to them - + * entities and collections + */ +public interface Restrictable { + + /** + * Apply {@link org.hibernate.annotations.Filter} and + * {@link org.hibernate.annotations.Where} restrictions + */ + void applyRestrictions( + QuerySpec querySpec, + TableGroup tableGroup, + boolean useQualifier, + Map enabledFilters, + Set treatAsDeclarations, + FromClauseAccess fromClauseAccess); + + /** + * Apply {@link org.hibernate.annotations.Filter} and + * {@link org.hibernate.annotations.Where} restrictions + */ + void applyRestrictions( + RestrictionPredicateConsumer predicateConsumer, + TableGroup tableGroup, + boolean useQualifier, + Map enabledFilters, + Set treatAsDeclarations, + FromClauseAccess fromClauseAccess); + + enum RestrictionPredicatePartType { + ENTITY, + COLLECTION, + MANY_TO_MANY, + ONE_TO_MANY + } + + enum RestrictionSourceType { + /** + * {@link org.hibernate.annotations.Where} + */ + WHERE, + /** + * {@link org.hibernate.annotations.Filter} + */ + FILTER + } + + @FunctionalInterface + interface RestrictionPredicateConsumer { + void consume(Predicate predicate, Joinable.RestrictionPredicatePartType partType, Joinable.RestrictionSourceType sourceType); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index b4f9c365d7..29baeeeb8f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; +import java.util.function.Consumer; import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; @@ -119,7 +120,7 @@ import org.hibernate.sql.ast.tree.expression.AliasedExpression; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableReference; -import org.hibernate.sql.ast.tree.predicate.FilterPredicate; +import org.hibernate.sql.ast.tree.predicate.Predicate; import org.hibernate.sql.ast.tree.select.QuerySpec; import org.hibernate.sql.ast.tree.select.SelectClause; import org.hibernate.sql.ast.tree.select.SelectStatement; @@ -134,7 +135,11 @@ import org.hibernate.type.Type; import org.jboss.logging.Logger; -import static org.hibernate.internal.FilterHelper.doCreateFilterPredicate; +import static org.hibernate.metamodel.mapping.Restrictable.RestrictionPredicatePartType.COLLECTION; +import static org.hibernate.metamodel.mapping.Restrictable.RestrictionPredicatePartType.MANY_TO_MANY; +import static org.hibernate.metamodel.mapping.Restrictable.RestrictionPredicatePartType.ONE_TO_MANY; +import static org.hibernate.metamodel.mapping.Restrictable.RestrictionSourceType.FILTER; +import static org.hibernate.metamodel.mapping.Restrictable.RestrictionSourceType.WHERE; /** * Base implementation of the QueryableCollection interface. @@ -2036,58 +2041,113 @@ public abstract class AbstractCollectionPersister applyOneToManyWhereRestriction( alias, tableGroup, querySpec, tableGroupJoin ); } + /** + * Apply both {@link org.hibernate.annotations.Filter} and + * {@link org.hibernate.annotations.Where} restrictions + */ + @Override + public void applyRestrictions( + RestrictionPredicateConsumer predicateConsumer, + TableGroup tableGroup, + boolean useQualifier, + Map enabledFilters, + Set treatAsDeclarations, + FromClauseAccess fromClauseAccess) { + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // handle `@Filter` + applyFilterRestrictions( predicateConsumer, tableGroup, enabledFilters, fromClauseAccess ); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // handle `@Where` + TableReference tableReference; + if ( isManyToMany() ) { + tableReference = tableGroup.getPrimaryTableReference(); + } + else if ( elementPersister instanceof Joinable ) { + tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), ( (Joinable) elementPersister ).getTableName() ); + } + else { + tableReference = tableGroup.getTableReference( tableGroup.getNavigablePath(), qualifiedTableName ); + } + + final String alias; + if ( tableReference == null ) { + alias = null; + } + else if ( useQualifier && tableReference.getIdentificationVariable() != null ) { + alias = tableReference.getIdentificationVariable(); + } + else { + alias = tableReference.getTableExpression(); + } + + applyWhereRestriction( alias, (predicate) -> predicateConsumer.consume( predicate, COLLECTION, WHERE ) ); + applyManyToManyWhereRestriction( tableGroup, (predicate) -> predicateConsumer.consume( predicate, MANY_TO_MANY, WHERE ) ); + applyOneToManyWhereRestriction( alias, tableGroup, (predicate) -> predicateConsumer.consume( predicate, ONE_TO_MANY, WHERE ) ); + } + protected void applyFilterRestrictions( QuerySpec querySpec, TableGroup tableGroup, Map enabledFilters, TableGroupJoin pluralTableGroupJoin) { if ( filterHelper != null ) { - final StringBuilder fragment = new StringBuilder(); - filterHelper.render( fragment, getFilterAliasGenerator( tableGroup ), enabledFilters ); - if ( fragment.length() > 1 ) { - final FilterPredicate filterPredicate = doCreateFilterPredicate( fragment.toString(), enabledFilters ); - if ( pluralTableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } - } + filterHelper.applyFilters( querySpec, getFilterAliasGenerator( tableGroup ), enabledFilters ); } if ( manyToManyFilterHelper != null ) { assert elementPersister instanceof Joinable; assert isManyToMany(); - final StringBuilder fragment = new StringBuilder(); - manyToManyFilterHelper.render( fragment, elementPersister.getFilterAliasGenerator( tableGroup ), enabledFilters ); - if ( fragment.length() > 1 ) { - final FilterPredicate filterPredicate = doCreateFilterPredicate( fragment.toString(), enabledFilters ); - if ( pluralTableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } - } + manyToManyFilterHelper.applyFilters( + getFilterAliasGenerator( tableGroup ), + enabledFilters, + (predicate) -> { + final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent(); + if ( parentNavigablePath == null ) { + querySpec.applyPredicate( predicate ); + } + else { + final TableGroup parentTableGroup = fromClauseAccess.getTableGroup( parentNavigablePath ); + TableGroupJoin pluralTableGroupJoin = null; + for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { + if ( nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath() ) { + pluralTableGroupJoin = nestedTableGroupJoin; + break; + } + } + + assert pluralTableGroupJoin != null; + pluralTableGroupJoin.applyPredicate( predicate ); + } + } + ); } } - private static TableGroupJoin findTableGroupJoin(TableGroup tableGroup, FromClauseAccess fromClauseAccess) { - final NavigablePath parentNavigablePath; - if ( tableGroup == null || ( parentNavigablePath = tableGroup.getNavigablePath().getParent() ) == null ) { - return null; + protected void applyFilterRestrictions( + RestrictionPredicateConsumer predicateConsumer, + TableGroup tableGroup, + Map enabledFilters, + FromClauseAccess fromClauseAccess) { + if ( filterHelper != null ) { + filterHelper.applyFilters( + getFilterAliasGenerator( tableGroup ), + enabledFilters, + (filterPredicate) -> predicateConsumer.consume( filterPredicate, COLLECTION, FILTER ) + ); } - else { - final TableGroup parentTableGroup = fromClauseAccess.getTableGroup( parentNavigablePath ); - TableGroupJoin pluralTableGroupJoin = null; - for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { - if ( nestedTableGroupJoin.getNavigablePath() == tableGroup.getNavigablePath() ) { - pluralTableGroupJoin = nestedTableGroupJoin; - break; - } - } + if ( manyToManyFilterHelper != null ) { + assert elementPersister instanceof Joinable; + assert isManyToMany(); + + final TableReference tableReference = tableGroup.resolveTableReference( ( (Joinable) elementPersister ).getTableName() ); + manyToManyFilterHelper.applyFilters( + getFilterAliasGenerator( tableReference.getIdentificationVariable() ), + enabledFilters, + (filterPredicate) -> predicateConsumer.consume( filterPredicate, MANY_TO_MANY, FILTER ) + ); assert pluralTableGroupJoin != null; return pluralTableGroupJoin; } @@ -2097,16 +2157,14 @@ public abstract class AbstractCollectionPersister String alias, QuerySpec querySpec, TableGroupJoin pluralTableGroupJoin) { + applyWhereRestriction( alias, querySpec::applyPredicate ); + } + + protected void applyWhereRestriction(String alias, Consumer predicateConsumer) { if ( sqlWhereString != null ) { final String whereCondition = getSQLWhereString( alias ); assert whereCondition != null; - final WhereFilterPredicate filterPredicate = new WhereFilterPredicate( whereCondition ); - if ( pluralTableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } + predicateConsumer.accept( new WhereFilterPredicate( whereCondition ) ); } } @@ -2114,6 +2172,10 @@ public abstract class AbstractCollectionPersister TableGroup tableGroup, QuerySpec querySpec, TableGroupJoin pluralTableGroupJoin) { + applyManyToManyWhereRestriction( tableGroup, querySpec::applyPredicate ); + } + + public void applyManyToManyWhereRestriction(TableGroup tableGroup, Consumer predicateConsumer) { if ( manyToManyWhereString == null ) { return; } @@ -2121,13 +2183,7 @@ public abstract class AbstractCollectionPersister final TableReference tableReference = tableGroup.resolveTableReference( ( (Joinable) elementPersister ).getTableName() ); final String condition = StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, tableReference.getIdentificationVariable() ); assert StringHelper.isNotEmpty( condition ); - final WhereFilterPredicate filterPredicate = new WhereFilterPredicate( condition ); - if ( pluralTableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } + predicateConsumer.accept( new WhereFilterPredicate( condition ) ); } private void applyOneToManyWhereRestriction( @@ -2135,6 +2191,10 @@ public abstract class AbstractCollectionPersister TableGroup tableGroup, QuerySpec querySpec, TableGroupJoin pluralTableGroupJoin) { + applyOneToManyWhereRestriction( alias, tableGroup, querySpec::applyPredicate ); + } + + private void applyOneToManyWhereRestriction(String alias, TableGroup tableGroup, Consumer predicateConsumer) { if ( ! isOneToMany() ) { return; } @@ -2145,13 +2205,7 @@ public abstract class AbstractCollectionPersister final String associationWhereCondition = ( (Joinable) getElementPersister() ).oneToManyFilterFragment( alias, null ); if ( StringHelper.isNotEmpty( associationWhereCondition ) ) { - final WhereFilterPredicate filterPredicate = new WhereFilterPredicate( associationWhereCondition ); - if ( pluralTableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - pluralTableGroupJoin.applyPredicate( filterPredicate ); - } + predicateConsumer.accept( new WhereFilterPredicate( associationWhereCondition ) ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 76db831643..f3f20fdf55 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -268,8 +268,6 @@ import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.spi.TypeConfiguration; -import static org.hibernate.internal.FilterHelper.doCreateFilterPredicate; - /** * Basic functionality for persisting an entity via JDBC * through either generated or custom SQL @@ -1052,7 +1050,12 @@ public abstract class AbstractEntityPersister propertyDefinedOnSubclass = ArrayHelper.toBooleanArray( definedBySubclass ); // Handle any filters applied to the class level - filterHelper = new FilterHelper( bootDescriptor.getFilters(), factory ); + if ( CollectionHelper.isEmpty( bootDescriptor.getFilters() ) ) { + filterHelper = null; + } + else { + filterHelper = new FilterHelper( bootDescriptor.getFilters(), factory ); + } // Check if we can use Reference Cached entities in 2lc // todo : should really validate that the cache access type is read-only @@ -1337,7 +1340,7 @@ public abstract class AbstractEntityPersister creationContext ); - return new StandardTableGroup( + final StandardTableGroup tableGroup = new StandardTableGroup( canUseInnerJoins, navigablePath, this, @@ -1346,10 +1349,10 @@ public abstract class AbstractEntityPersister true, sqlAliasBase, (tableExpression) -> ArrayHelper.contains( getSubclassTableNames(), tableExpression ), - (tableExpression, tableGroup) -> { + (tableExpression, tg) -> { final String[] subclassTableNames = getSubclassTableNames(); for ( int i = 0; i < subclassTableNames.length; i++ ) { - if ( tableExpression.equals( subclassTableNames[i] ) ) { + if ( tableExpression.equals( subclassTableNames[ i ] ) ) { final boolean isNullableTable = isNullableSubclassTable( i ); final TableReference joinedTableReference = new TableReference( tableExpression, @@ -1367,11 +1370,11 @@ public abstract class AbstractEntityPersister additionalPredicateCollectorAccess == null ? null : generateJoinPredicate( - primaryTableReference, - joinedTableReference, - getSubclassTableKeyColumns( i ), - sqlExpressionResolver - ) + primaryTableReference, + joinedTableReference, + getSubclassTableKeyColumns( i ), + sqlExpressionResolver + ) ); } } @@ -1380,6 +1383,8 @@ public abstract class AbstractEntityPersister }, getFactory() ); + + return tableGroup; } @Override @@ -3992,6 +3997,10 @@ public abstract class AbstractEntityPersister @Override public String filterFragment(String alias, Map enabledFilters, Set treatAsDeclarations) { + if ( filterHelper == null ) { + return ""; + } + final StringBuilder sessionFilterFragment = new StringBuilder(); filterHelper.render( sessionFilterFragment, alias == null ? null : getFilterAliasGenerator( alias ), enabledFilters ); final String filterFragment = filterFragment( alias, treatAsDeclarations ); @@ -4007,6 +4016,10 @@ public abstract class AbstractEntityPersister Map enabledFilters, Set treatAsDeclarations, boolean useIdentificationVariable) { + if ( filterHelper == null ) { + return null; + } + final String alias; if ( tableGroup == null ) { alias = null; @@ -4017,6 +4030,7 @@ public abstract class AbstractEntityPersister else { alias = tableGroup.getPrimaryTableReference().getTableExpression(); } + final StringBuilder sessionFilterFragment = new StringBuilder(); filterHelper.render( sessionFilterFragment, !useIdentificationVariable || tableGroup == null ? null : getFilterAliasGenerator( tableGroup ), enabledFilters ); final String filterFragment = filterFragment( alias, treatAsDeclarations ); @@ -4030,6 +4044,42 @@ public abstract class AbstractEntityPersister return alias; } + @Override + public void applyRestrictions( + RestrictionPredicateConsumer predicateConsumer, + TableGroup tableGroup, + boolean useQualifier, + Map enabledFilters, + Set treatAsDeclarations, + FromClauseAccess fromClauseAccess) { + // handle `@Filter` + final FilterAliasGenerator aliasGenerator = useQualifier && tableGroup != null + ? getFilterAliasGenerator( tableGroup ) + : null; + applyFilterRestrictions( + enabledFilters, + aliasGenerator, + (predicate) -> predicateConsumer.consume( predicate, RestrictionPredicatePartType.ENTITY, RestrictionSourceType.FILTER ) + ); + + // handle `@Where` + final String alias; + if ( tableGroup == null ) { + alias = null; + } + else if ( useQualifier && tableGroup.getPrimaryTableReference().getIdentificationVariable() != null ) { + alias = tableGroup.getPrimaryTableReference().getIdentificationVariable(); + } + else { + alias = tableGroup.getPrimaryTableReference().getTableExpression(); + } + applyWhereRestriction( + generateWhereConditionAlias( alias ), + treatAsDeclarations, + (predicate) -> predicateConsumer.consume( predicate, RestrictionPredicatePartType.ENTITY, RestrictionSourceType.WHERE ) + ); + } + /** * Apply both {@link org.hibernate.annotations.Filter} and * {@link org.hibernate.annotations.Where} restrictions @@ -4048,7 +4098,7 @@ public abstract class AbstractEntityPersister final FilterAliasGenerator aliasGenerator = useQualifier && tableGroup != null ? getFilterAliasGenerator( tableGroup ) : null; - applyFilterRestrictions( querySpec, tableGroup, enabledFilters, aliasGenerator, tableGroupJoin ); + applyFilterRestrictions( querySpec, enabledFilters, aliasGenerator, tableGroupJoin ); // handle `@Where` final String alias; @@ -4064,22 +4114,31 @@ public abstract class AbstractEntityPersister applyWhereRestriction( generateWhereConditionAlias( alias ), treatAsDeclarations, querySpec, tableGroupJoin ); } + @Override + public FilterPredicate generateFilterPredicate(TableGroup tableGroup, boolean useQualifier, Set treatAsDeclarations, Map enabledFilters) { + if ( filterHelper == null ) { + return null; + } + + final FilterAliasGenerator aliasGenerator = useQualifier && tableGroup != null + ? getFilterAliasGenerator( tableGroup ) + : null; + return filterHelper.generateFilterPredicate( aliasGenerator, enabledFilters ); + } + protected void applyFilterRestrictions( QuerySpec querySpec, - TableGroup tableGroup, Map enabledFilters, - FilterAliasGenerator aliasGenerator, - TableGroupJoin tableGroupJoin) { - final StringBuilder fragment = new StringBuilder(); - filterHelper.render( fragment, aliasGenerator, enabledFilters ); - if ( fragment.length() > 1 ) { - final FilterPredicate filterPredicate = doCreateFilterPredicate( fragment.toString(), enabledFilters ); - if ( tableGroupJoin == null ) { - querySpec.applyPredicate( filterPredicate ); - } - else { - tableGroupJoin.applyPredicate( filterPredicate ); - } + FilterAliasGenerator aliasGenerator) { + if ( filterHelper != null ) { + filterHelper.applyFilters( querySpec, aliasGenerator, enabledFilters ); + } + } + + protected void applyFilterRestrictions( + Map enabledFilters, FilterAliasGenerator aliasGenerator, Consumer predicateConsumer) { + if ( filterHelper != null ) { + filterHelper.applyFilters( aliasGenerator, enabledFilters, (Consumer) predicateConsumer ); } } @@ -4116,6 +4175,13 @@ public abstract class AbstractEntityPersister } } + protected void applyWhereRestriction(String alias, Set treatAsDeclarations, Consumer predicateConsumer) { + if ( hasWhere() ) { + final String whereCondition = getSQLWhereString( alias ); + predicateConsumer.accept( new WhereFilterPredicate( whereCondition ) ); + } + } + public String generateFilterConditionAlias(String rootAlias) { return rootAlias; } @@ -4398,7 +4464,7 @@ public abstract class AbstractEntityPersister @Override public boolean isAffectedByEnabledFilters(LoadQueryInfluencers loadQueryInfluencers) { - if ( loadQueryInfluencers.hasEnabledFilters() ) { + if ( loadQueryInfluencers.hasEnabledFilters() && filterHelper != null ) { if ( filterHelper.isAffectedBy( loadQueryInfluencers.getEnabledFilters() ) ) { return true; } diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java index 8a424aa224..d4a008f81f 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/Joinable.java @@ -5,15 +5,15 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.persister.entity; + import java.util.Collections; import java.util.Map; import java.util.Set; import org.hibernate.Filter; import org.hibernate.MappingException; -import org.hibernate.sql.ast.spi.FromClauseAccess; +import org.hibernate.metamodel.mapping.Restrictable; import org.hibernate.sql.ast.tree.from.TableGroup; -import org.hibernate.sql.ast.tree.select.QuerySpec; /** * Anything that can be loaded by outer join - namely @@ -21,7 +21,7 @@ import org.hibernate.sql.ast.tree.select.QuerySpec; * * @author Gavin King */ -public interface Joinable { +public interface Joinable extends Restrictable { //should this interface extend PropertyMapping? /** @@ -38,18 +38,6 @@ public interface Joinable { */ public String[] getKeyColumnNames(); - /** - * Apply {@link org.hibernate.annotations.Filter} and - * {@link org.hibernate.annotations.Where} restrictions - */ - void applyRestrictions( - QuerySpec querySpec, - TableGroup tableGroup, - boolean useQualifier, - Map enabledFilters, - Set treatAsDeclarations, - FromClauseAccess fromClauseAccess); - /** * Get the where clause filter, given a query alias and considering enabled session filters */ diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java index f89748716b..045f43415a 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/MatchingIdSelectionHelper.java @@ -116,15 +116,13 @@ public class MatchingIdSelectionHelper { ); sqmConverter.getProcessingStateStack().pop(); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - executionContext.getSession().getLoadQueryInfluencers(), - (Joinable) targetEntityDescriptor.getEntityPersister(), - mutatingTableGroup + final FilterPredicate filterPredicate = targetEntityDescriptor.getEntityPersister().generateFilterPredicate( + mutatingTableGroup, + true, + Collections.emptySet(), + executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters() ); - if ( filterPredicate != null ) { - restriction = SqlAstTreeHelper.combinePredicates( restriction, filterPredicate ); - } - idSelectionQuery.applyPredicate( restriction ); + idSelectionQuery.applyPredicate( SqlAstTreeHelper.combinePredicates( restriction, filterPredicate ) ); return new SelectStatement( idSelectionQuery, domainResults ); } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java index 0216e00fc1..83db93ad76 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/RestrictedDeleteExecutionDelegate.java @@ -156,10 +156,11 @@ public class RestrictedDeleteExecutionDelegate implements TableBasedDeleteHandle } ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - executionContext.getSession().getLoadQueryInfluencers(), - (Joinable) entityDescriptor, - deletingTableGroup + final FilterPredicate filterPredicate = entityDescriptor.generateFilterPredicate( + deletingTableGroup, + true, + Collections.emptySet(), + executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters() ); if ( filterPredicate != null ) { needsIdTableWrapper.setValue( true ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java index d720e25c60..11e46df223 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/TableBasedUpdateHandler.java @@ -186,10 +186,11 @@ public class TableBasedUpdateHandler assert predicate != null; } - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - executionContext.getSession().getLoadQueryInfluencers(), - (Joinable) rootEntityDescriptor, - updatingTableGroup + final FilterPredicate filterPredicate = entityDescriptor.generateFilterPredicate( + updatingTableGroup, + true, + Collections.emptySet(), + executionContext.getSession().getLoadQueryInfluencers().getEnabledFilters() ); if ( filterPredicate != null ) { predicate = SqlAstTreeHelper.combinePredicates( predicate, filterPredicate ); diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index cab2a35c41..bd29c7b6ac 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -26,7 +26,6 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import jakarta.persistence.TemporalType; import org.hibernate.HibernateException; import org.hibernate.Internal; @@ -47,7 +46,6 @@ import org.hibernate.id.IdentifierGenerator; import org.hibernate.id.OptimizableGenerator; import org.hibernate.id.PostInsertIdentifierGenerator; import org.hibernate.id.enhanced.Optimizer; -import org.hibernate.internal.FilterHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.internal.util.collections.Stack; import org.hibernate.internal.util.collections.StandardStack; @@ -62,6 +60,7 @@ import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.Bindable; import org.hibernate.metamodel.mapping.CollectionPart; import org.hibernate.metamodel.mapping.ConvertibleModelPart; +import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart; import org.hibernate.metamodel.mapping.EntityAssociationMapping; import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping; @@ -70,18 +69,18 @@ import org.hibernate.metamodel.mapping.EntityMappingType; import org.hibernate.metamodel.mapping.EntityValuedModelPart; import org.hibernate.metamodel.mapping.EntityVersionMapping; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; -import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.metamodel.mapping.MappingModelExpressable; import org.hibernate.metamodel.mapping.ModelPart; import org.hibernate.metamodel.mapping.ModelPartContainer; import org.hibernate.metamodel.mapping.PluralAttributeMapping; +import org.hibernate.metamodel.mapping.Restrictable; +import org.hibernate.metamodel.mapping.Restrictable.RestrictionPredicatePartType; import org.hibernate.metamodel.mapping.SqlExpressable; import org.hibernate.metamodel.mapping.ValueMapping; import org.hibernate.metamodel.mapping.internal.EmbeddedCollectionPart; import org.hibernate.metamodel.mapping.internal.EntityCollectionPart; -import org.hibernate.metamodel.mapping.internal.ExplicitColumnDiscriminatorMappingImpl; import org.hibernate.metamodel.mapping.internal.ToOneAttributeMapping; import org.hibernate.metamodel.mapping.ordering.OrderByFragment; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; @@ -121,6 +120,8 @@ import org.hibernate.query.QueryLogging; import org.hibernate.query.SemanticException; import org.hibernate.query.TemporalUnit; import org.hibernate.query.UnaryArithmeticOperator; +import org.hibernate.query.criteria.JpaPath; +import org.hibernate.query.internal.QueryHelper; import org.hibernate.query.spi.QueryOptions; import org.hibernate.query.spi.QueryParameterBinding; import org.hibernate.query.spi.QueryParameterBindings; @@ -131,8 +132,10 @@ import org.hibernate.query.sqm.SqmPathSource; import org.hibernate.query.sqm.SqmQuerySource; import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor; import org.hibernate.query.sqm.function.SelfRenderingAggregateFunctionSqlAstExpression; +import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression; import org.hibernate.query.sqm.internal.DomainParameterXref; import org.hibernate.query.sqm.internal.SqmMappingModelHelper; +import org.hibernate.query.sqm.produce.function.internal.PatternRenderer; import org.hibernate.query.sqm.spi.BaseSemanticQueryWalker; import org.hibernate.query.sqm.sql.internal.BasicValuedPathInterpretation; import org.hibernate.query.sqm.sql.internal.DiscriminatedAssociationPathInterpretation; @@ -148,6 +151,7 @@ import org.hibernate.query.sqm.sql.internal.SqmMapEntryResult; import org.hibernate.query.sqm.sql.internal.SqmParameterInterpretation; import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation; import org.hibernate.query.sqm.sql.internal.TypeHelper; +import org.hibernate.query.sqm.tree.SqmJoinType; import org.hibernate.query.sqm.tree.SqmStatement; import org.hibernate.query.sqm.tree.SqmTypedNode; import org.hibernate.query.sqm.tree.cte.SqmCteContainer; @@ -160,6 +164,8 @@ import org.hibernate.query.sqm.tree.domain.AbstractSqmSpecificPluralPartPath; import org.hibernate.query.sqm.tree.domain.NonAggregatedCompositeSimplePath; import org.hibernate.query.sqm.tree.domain.SqmAnyValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmBasicValuedSimplePath; +import org.hibernate.query.sqm.tree.domain.SqmCorrelatedRootJoin; +import org.hibernate.query.sqm.tree.domain.SqmCorrelation; import org.hibernate.query.sqm.tree.domain.SqmEmbeddedValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmEntityValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmIndexedCollectionAccessPath; @@ -171,6 +177,7 @@ import org.hibernate.query.sqm.tree.domain.SqmMinIndexPath; import org.hibernate.query.sqm.tree.domain.SqmPath; import org.hibernate.query.sqm.tree.domain.SqmPluralValuedSimplePath; import org.hibernate.query.sqm.tree.domain.SqmTreatedPath; +import org.hibernate.query.sqm.tree.domain.SqmTreatedRoot; import org.hibernate.query.sqm.tree.expression.Conversion; import org.hibernate.query.sqm.tree.expression.JpaCriteriaParameter; import org.hibernate.query.sqm.tree.expression.SqmAliasedNodeRef; @@ -195,6 +202,7 @@ import org.hibernate.query.sqm.tree.expression.SqmJpaCriteriaParameterWrapper; import org.hibernate.query.sqm.tree.expression.SqmLiteral; import org.hibernate.query.sqm.tree.expression.SqmLiteralEntityType; import org.hibernate.query.sqm.tree.expression.SqmLiteralNull; +import org.hibernate.query.sqm.tree.expression.SqmModifiedSubQueryExpression; import org.hibernate.query.sqm.tree.expression.SqmNamedParameter; import org.hibernate.query.sqm.tree.expression.SqmParameter; import org.hibernate.query.sqm.tree.expression.SqmParameterizedEntityType; @@ -213,6 +221,7 @@ import org.hibernate.query.sqm.tree.from.SqmFromClause; import org.hibernate.query.sqm.tree.from.SqmJoin; import org.hibernate.query.sqm.tree.from.SqmRoot; import org.hibernate.query.sqm.tree.insert.SqmInsertSelectStatement; +import org.hibernate.query.sqm.tree.insert.SqmInsertStatement; import org.hibernate.query.sqm.tree.insert.SqmInsertValuesStatement; import org.hibernate.query.sqm.tree.insert.SqmValues; import org.hibernate.query.sqm.tree.predicate.SqmAndPredicate; @@ -289,16 +298,21 @@ import org.hibernate.sql.ast.tree.expression.ExtractUnit; import org.hibernate.sql.ast.tree.expression.Format; import org.hibernate.sql.ast.tree.expression.JdbcLiteral; import org.hibernate.sql.ast.tree.expression.JdbcParameter; +import org.hibernate.sql.ast.tree.expression.ModifiedSubQueryExpression; +import org.hibernate.sql.ast.tree.expression.Over; import org.hibernate.sql.ast.tree.expression.QueryLiteral; import org.hibernate.sql.ast.tree.expression.SelfRenderingExpression; +import org.hibernate.sql.ast.tree.expression.SelfRenderingSqlFragmentExpression; import org.hibernate.sql.ast.tree.expression.SqlSelectionExpression; import org.hibernate.sql.ast.tree.expression.SqlTuple; import org.hibernate.sql.ast.tree.expression.Star; import org.hibernate.sql.ast.tree.expression.Summarization; import org.hibernate.sql.ast.tree.expression.TrimSpecification; import org.hibernate.sql.ast.tree.expression.UnaryOperation; +import org.hibernate.sql.ast.tree.from.CorrelatedPluralTableGroup; import org.hibernate.sql.ast.tree.from.CorrelatedTableGroup; import org.hibernate.sql.ast.tree.from.LazyTableGroup; +import org.hibernate.sql.ast.tree.from.PluralTableGroup; import org.hibernate.sql.ast.tree.from.TableGroup; import org.hibernate.sql.ast.tree.from.TableGroupJoin; import org.hibernate.sql.ast.tree.from.TableGroupJoinProducer; @@ -331,6 +345,7 @@ import org.hibernate.sql.ast.tree.update.Assignment; import org.hibernate.sql.ast.tree.update.UpdateStatement; import org.hibernate.sql.exec.internal.JdbcParameterImpl; import org.hibernate.sql.exec.internal.JdbcParametersImpl; +import org.hibernate.sql.exec.internal.VersionTypeSeedParameterSpecification; import org.hibernate.sql.exec.spi.ExecutionContext; import org.hibernate.sql.exec.spi.JdbcParameterBindings; import org.hibernate.sql.exec.spi.JdbcParameters; @@ -352,6 +367,8 @@ import org.hibernate.usertype.UserVersionType; import org.jboss.logging.Logger; +import jakarta.persistence.TemporalType; + import static org.hibernate.internal.util.NullnessHelper.coalesceSuppliedValues; import static org.hibernate.query.BinaryArithmeticOperator.ADD; import static org.hibernate.query.BinaryArithmeticOperator.MULTIPLY; @@ -391,7 +408,7 @@ public abstract class BaseSqmToSqlAstConverter extends Base private ForeignKeyDescriptor.Nature currentlyResolvingForeignKeySide; private SqmQueryPart currentSqmQueryPart; - private Map collectionFilterPredicates; + private final Map> collectionFilterPredicates = new HashMap<>(); private List> orderByFragments; private final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager(); @@ -670,12 +687,11 @@ public abstract class BaseSqmToSqlAstConverter extends Base final List assignments = visitSetClause( sqmStatement.getSetClause() ); addVersionedAssignment( assignments::add, sqmStatement ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) entityDescriptor, + final FilterPredicate filterPredicate = entityDescriptor.generateFilterPredicate( rootTableGroup, - // todo (6.0): this is temporary until we implement proper alias support - AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.UPDATE ) + AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.UPDATE ), + Collections.emptySet(), + loadQueryInfluencers.getEnabledFilters() ); if ( filterPredicate != null ) { additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, filterPredicate ); @@ -900,12 +916,11 @@ public abstract class BaseSqmToSqlAstConverter extends Base throw new HibernateException( "Not expecting multiple table references for an SQM DELETE" ); } - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) entityDescriptor, + final FilterPredicate filterPredicate = entityDescriptor.generateFilterPredicate( rootTableGroup, - // todo (6.0): this is temporary until we implement proper alias support - AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.DELETE ) + AbstractSqlAstTranslator.rendersTableReferenceAlias( Clause.DELETE ), + Collections.emptySet(), + loadQueryInfluencers.getEnabledFilters() ); if ( filterPredicate != null ) { additionalRestrictions = SqlAstTreeHelper.combinePredicates( additionalRestrictions, filterPredicate ); @@ -1747,22 +1762,17 @@ public abstract class BaseSqmToSqlAstConverter extends Base final ModelPartContainer modelPartContainer = root.getModelPart(); final EntityPersister entityPersister = modelPartContainer.findContainingEntityMapping().getEntityPersister(); assert entityPersister instanceof Joinable; - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), (Joinable) entityPersister, root - ); - if ( filterPredicate != null ) { - sqlQuerySpec.applyPredicate( filterPredicate ); - } + if ( CollectionHelper.isNotEmpty( collectionFilterPredicates ) ) { - root.getTableGroupJoins().forEach( - tableGroupJoin -> { - collectionFilterPredicates.forEach( (alias, predicate) -> { - if ( tableGroupJoin.getJoinedGroup().getGroupAlias().equals( alias ) ) { - tableGroupJoin.applyPredicate( predicate ); - } - } ); + root.getTableGroupJoins().forEach( (tableGroupJoin) -> { + collectionFilterPredicates.forEach( (alias, predicates) -> { + if ( tableGroupJoin.getJoinedGroup().getGroupAlias().equals( alias ) ) { + if ( CollectionHelper.isNotEmpty( predicates ) ) { + predicates.forEach( tableGroupJoin::applyPredicate ); + } } - ); + } ); + } ); } } } @@ -2319,14 +2329,15 @@ public abstract class BaseSqmToSqlAstConverter extends Base this, creationContext ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) entityDescriptor, - tableGroup + + ( (Restrictable) entityDescriptor ).applyRestrictions( + currentQuerySpec, + tableGroup, + true, + loadQueryInfluencers.getEnabledFilters(), + Collections.emptySet(), + getFromClauseAccess() ); - if ( filterPredicate != null ) { - currentQuerySpec.applyPredicate( filterPredicate ); - } } log.tracef( "Resolved SqmRoot [%s] to new TableGroup [%s]", sqmRoot, tableGroup ); @@ -3242,14 +3253,15 @@ public abstract class BaseSqmToSqlAstConverter extends Base this, creationContext ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) pluralAttributeMapping.getCollectionDescriptor(), - tableGroup + + ( (Joinable) pluralAttributeMapping.getCollectionDescriptor() ).applyRestrictions( + subQuerySpec, + tableGroup, + true, + getLoadQueryInfluencers().getEnabledFilters(), + Collections.emptySet(), + getFromClauseAccess() ); - if ( filterPredicate != null ) { - subQuerySpec.applyPredicate( filterPredicate ); - } getFromClauseAccess().registerTableGroup( pluralPath.getNavigablePath(), tableGroup ); registerPluralTableGroupParts( tableGroup ); @@ -3385,14 +3397,15 @@ public abstract class BaseSqmToSqlAstConverter extends Base this, creationContext ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) pluralAttributeMapping.getCollectionDescriptor(), - tableGroup + + ( (Joinable) pluralAttributeMapping.getCollectionDescriptor() ).applyRestrictions( + subQuerySpec, + tableGroup, + true, + getLoadQueryInfluencers().getEnabledFilters(), + Collections.emptySet(), + getFromClauseAccess() ); - if ( filterPredicate != null ) { - subQuerySpec.applyPredicate( filterPredicate ); - } getFromClauseAccess().registerTableGroup( pluralPartPath.getNavigablePath(), tableGroup ); registerPluralTableGroupParts( tableGroup ); @@ -5023,14 +5036,15 @@ public abstract class BaseSqmToSqlAstConverter extends Base this, creationContext ); - final FilterPredicate filterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - (Joinable) pluralAttributeMapping.getCollectionDescriptor(), - tableGroup + + ( (Joinable) pluralAttributeMapping.getCollectionDescriptor() ).applyRestrictions( + subQuerySpec, + tableGroup, + true, + getLoadQueryInfluencers().getEnabledFilters(), + Collections.emptySet(), + getFromClauseAccess() ); - if ( filterPredicate != null ) { - subQuerySpec.applyPredicate( filterPredicate ); - } getFromClauseAccess().registerTableGroup( pluralPath.getNavigablePath(), tableGroup ); registerPluralTableGroupParts( tableGroup ); @@ -5661,44 +5675,36 @@ public abstract class BaseSqmToSqlAstConverter extends Base if ( fetchable instanceof PluralAttributeMapping && fetch.getTiming() == FetchTiming.IMMEDIATE && joined ) { final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) fetchable; - - final Joinable joinable = pluralAttributeMapping - .getCollectionDescriptor() - .getCollectionType() - .getAssociatedJoinable( getCreationContext().getSessionFactory() ); final TableGroup tableGroup = getFromClauseIndex().getTableGroup( fetchablePath ); - final FilterPredicate collectionFieldFilterPredicate = FilterHelper.createFilterPredicate( - getLoadQueryInfluencers(), - joinable, - tableGroup - ); - if ( collectionFieldFilterPredicate != null ) { - if ( collectionFilterPredicates == null ) { - collectionFilterPredicates = new HashMap<>(); - } - collectionFilterPredicates.put( tableGroup.getGroupAlias(), collectionFieldFilterPredicate ); - } - if ( pluralAttributeMapping.getCollectionDescriptor().isManyToMany() ) { - assert joinable instanceof CollectionPersister; - final Predicate manyToManyFilterPredicate = FilterHelper.createManyToManyFilterPredicate( - getLoadQueryInfluencers(), - ( CollectionPersister) joinable, - tableGroup - ); - if ( manyToManyFilterPredicate != null ) { - final TableGroup parentTableGroup = getFromClauseIndex().getTableGroup( fetchParent.getNavigablePath() ); - TableGroupJoin pluralTableGroupJoin = null; - for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { - if ( nestedTableGroupJoin.getNavigablePath() == fetchablePath ) { - pluralTableGroupJoin = nestedTableGroupJoin; - break; - } - } - assert pluralTableGroupJoin != null; - pluralTableGroupJoin.applyPredicate( manyToManyFilterPredicate ); - } - } + ( (Restrictable) pluralAttributeMapping.getCollectionDescriptor() ).applyRestrictions( + (predicate, partType, sourceType) -> { + if ( partType == RestrictionPredicatePartType.COLLECTION ) { + addCollectionFilterPredicate( tableGroup.getGroupAlias(), predicate ); + } + else if ( partType == RestrictionPredicatePartType.MANY_TO_MANY ) { + final TableGroup parentTableGroup = getFromClauseIndex().getTableGroup( fetchParent.getNavigablePath() ); + TableGroupJoin pluralTableGroupJoin = null; + for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) { + if ( nestedTableGroupJoin.getNavigablePath() == fetchablePath ) { + pluralTableGroupJoin = nestedTableGroupJoin; + break; + } + } + + assert pluralTableGroupJoin != null; + pluralTableGroupJoin.applyPredicate( predicate ); + } + else if ( partType == RestrictionPredicatePartType.ONE_TO_MANY ) { + addCollectionFilterPredicate( tableGroup.getGroupAlias(), predicate ); + } + }, + tableGroup, + true, + getLoadQueryInfluencers().getEnabledFilters(), + Collections.emptySet(), + getFromClauseAccess() + ); if ( currentQuerySpec().isRoot() ) { assert tableGroup.getModelPart() == pluralAttributeMapping; @@ -5721,6 +5727,18 @@ public abstract class BaseSqmToSqlAstConverter extends Base } } + private void addCollectionFilterPredicate(String groupAlias, Predicate predicate) { + final List existing = collectionFilterPredicates.get( groupAlias ); + if ( existing != null ) { + existing.add( predicate ); + } + else { + final ArrayList list = new ArrayList<>(); + list.add( predicate ); + collectionFilterPredicates.put( groupAlias, list ); + } + } + private void applyOrdering(TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping) { if ( pluralAttributeMapping.getOrderByFragment() != null ) { applyOrdering( tableGroup, pluralAttributeMapping.getOrderByFragment() ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java index c6ba9389c8..da409f7b6a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/SqlAstWalker.java @@ -157,6 +157,7 @@ public interface SqlAstWalker { void visitBetweenPredicate(BetweenPredicate betweenPredicate); void visitFilterPredicate(FilterPredicate filterPredicate); + void visitFilterFragmentPredicate(FilterPredicate.FilterFragmentPredicate fragmentPredicate); void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index c90b629fff..1e9a38cbd2 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -4279,15 +4279,23 @@ public abstract class AbstractSqlAstTranslator implemen @Override public void visitFilterPredicate(FilterPredicate filterPredicate) { - assert StringHelper.isNotEmpty( filterPredicate.getFilterFragment() ); - appendSql( filterPredicate.getFilterFragment() ); - for ( FilterJdbcParameter filterJdbcParameter : filterPredicate.getFilterJdbcParameters() ) { - parameterBinders.add( filterJdbcParameter.getBinder() ); - jdbcParameters.addParameter( filterJdbcParameter.getParameter() ); - filterJdbcParameters.add( filterJdbcParameter ); + visitJunction( filterPredicate.getFragments() ); + + final List parameters = filterPredicate.getParameters(); + if ( parameters != null ) { + for ( FilterJdbcParameter filterJdbcParameter : parameters ) { + parameterBinders.add( filterJdbcParameter.getBinder() ); + jdbcParameters.addParameter( filterJdbcParameter.getParameter() ); + filterJdbcParameters.add( filterJdbcParameter ); + } } } + @Override + public void visitFilterFragmentPredicate(FilterPredicate.FilterFragmentPredicate fragmentPredicate) { + appendSql( fragmentPredicate.getSqlFragment() ); + } + @Override public void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate) { assert StringHelper.isNotEmpty( whereFilterPredicate.getWhereCondition() ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java index 5eefacb76b..5387b2fcc0 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstWalker.java @@ -447,6 +447,10 @@ public class AbstractSqlAstWalker implements SqlAstWalker { public void visitFilterPredicate(FilterPredicate filterPredicate) { } + @Override + public void visitFilterFragmentPredicate(FilterPredicate.FilterFragmentPredicate fragmentPredicate) { + } + @Override public void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate) { } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java index aa4c9fccb9..629bbc7475 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/FilterPredicate.java @@ -6,6 +6,7 @@ */ package org.hibernate.sql.ast.tree.predicate; +import java.util.ArrayList; import java.util.List; import org.hibernate.internal.FilterJdbcParameter; @@ -21,17 +22,30 @@ import org.hibernate.sql.ast.SqlAstWalker; * @author Nathan Xu */ public class FilterPredicate implements Predicate { - private final String filterFragment; - private final List filterJdbcParameters; + private Junction fragments = new Junction(); + private List parameters; - public FilterPredicate(String filterFragment, List filterJdbcParameters) { - this.filterFragment = filterFragment; - this.filterJdbcParameters = filterJdbcParameters; + public FilterPredicate() { + } + + public void applyFragment(FilterFragmentPredicate predicate) { + fragments.add( predicate ); + } + + public void applyFragment(String sqlFragment) { + fragments.add( new FilterFragmentPredicate( sqlFragment ) ); + } + + public void applyParameter(FilterJdbcParameter parameter) { + if ( parameters == null ) { + parameters = new ArrayList<>(); + } + parameters.add( parameter ); } @Override public boolean isEmpty() { - return false; + return fragments.isEmpty(); } @Override @@ -39,16 +53,43 @@ public class FilterPredicate implements Predicate { sqlTreeWalker.visitFilterPredicate( this ); } - public String getFilterFragment() { - return filterFragment; + public Junction getFragments() { + return fragments; } - public List getFilterJdbcParameters() { - return filterJdbcParameters; + public List getParameters() { + return parameters; } @Override public JdbcMappingContainer getExpressionType() { return null; } + + public static class FilterFragmentPredicate implements Predicate { + private final String sqlFragment; + + public FilterFragmentPredicate(String sqlFragment) { + this.sqlFragment = sqlFragment; + } + + public String getSqlFragment() { + return sqlFragment; + } + + @Override + public void accept(SqlAstWalker sqlTreeWalker) { + sqlTreeWalker.visitFilterFragmentPredicate( this ); + } + + @Override + public JdbcMappingContainer getExpressionType() { + return null; + } + + @Override + public boolean isEmpty() { + return false; + } + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java index b7b32505e4..c6e49df4a9 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/tree/predicate/Junction.java @@ -31,6 +31,10 @@ public class Junction implements Predicate { private final JdbcMappingContainer expressionType; private final List predicates = new ArrayList<>(); + public Junction() { + this( Nature.CONJUNCTION ); + } + public Junction(Nature nature) { this( nature, null ); } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java index e74d164d0d..a48e1f24e5 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/cfg/persister/GoofyPersisterClassProvider.java @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Consumer; import org.hibernate.Filter; @@ -58,6 +59,7 @@ import org.hibernate.persister.walking.spi.CollectionElementDefinition; import org.hibernate.persister.walking.spi.CollectionIndexDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.predicate.FilterPredicate; import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; @@ -703,6 +705,11 @@ public class GoofyPersisterClassProvider implements PersisterClassResolver { public JavaType getMappedJavaTypeDescriptor() { return null; } + + @Override + public FilterPredicate generateFilterPredicate(TableGroup tableGroup, boolean useQualifier, Set treatAsDeclarations, Map enabledFilters) { + return null; + } } public static class NoopCollectionPersister implements CollectionPersister { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java index 05f31778f3..f53bbe64f3 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/ejb3configuration/PersisterClassProviderTest.java @@ -12,10 +12,12 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.Consumer; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.PersistenceException; +import org.hibernate.Filter; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -58,6 +60,8 @@ import org.hibernate.persister.spi.PersisterClassResolver; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.predicate.FilterPredicate; import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; @@ -717,6 +721,11 @@ public class PersisterClassProviderTest { public JavaType getMappedJavaTypeDescriptor() { return null; } + + @Override + public FilterPredicate generateFilterPredicate(TableGroup tableGroup, boolean useQualifier, Set treatAsDeclarations, Map enabledFilters) { + return null; + } } public static class GoofyException extends RuntimeException { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java index 01c8010250..f1aef86905 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/legacy/CustomPersister.java @@ -13,8 +13,10 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.function.Consumer; +import org.hibernate.Filter; import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.LockOptions; @@ -54,6 +56,8 @@ import org.hibernate.loader.ast.spi.MultiIdLoadOptions; import org.hibernate.persister.spi.PersisterCreationContext; import org.hibernate.persister.walking.spi.AttributeDefinition; import org.hibernate.persister.walking.spi.EntityIdentifierDefinition; +import org.hibernate.sql.ast.tree.from.TableGroup; +import org.hibernate.sql.ast.tree.predicate.FilterPredicate; import org.hibernate.tuple.entity.BytecodeEnhancementMetadataNonPojoImpl; import org.hibernate.tuple.entity.EntityMetamodel; import org.hibernate.tuple.entity.EntityTuplizer; @@ -818,4 +822,9 @@ public class CustomPersister implements EntityPersister { public JavaType getMappedJavaTypeDescriptor() { return null; } + + @Override + public FilterPredicate generateFilterPredicate(TableGroup tableGroup, boolean useQualifier, Set treatAsDeclarations, Map enabledFilters) { + return null; + } }