HHH-14977 - @Where is broken in 6.0
`@Where` and `@Filter` fragments are now fully handled as AST - each fragment gets its own Predicate instance. Some more work coming to clean up methods we no longer use which require the old String-manip approach.
This commit is contained in:
parent
4e4f2e40b4
commit
1c5ec0612c
|
@ -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<String, String>[] filterAliasTableMaps;
|
||||
private final List<String>[] parameterNames;
|
||||
|
||||
/**
|
||||
* The map of defined filters. This is expected to be in format
|
||||
|
@ -56,10 +56,13 @@ public class FilterHelper {
|
|||
*/
|
||||
public FilterHelper(List<FilterConfiguration> 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<String> 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(
|
||||
public void applyFilters(
|
||||
FilterAliasGenerator aliasGenerator,
|
||||
Map<String, Filter> enabledFilters,
|
||||
Joinable joinable,
|
||||
TableGroup rootTableGroup) {
|
||||
return createFilterPredicate( enabledFilters, joinable, rootTableGroup, true );
|
||||
}
|
||||
|
||||
public static FilterPredicate createFilterPredicate(
|
||||
Map<String,Filter> 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;
|
||||
Consumer<Predicate> 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<String, Filter> enabledFilters) {
|
||||
final FilterPredicate predicate = generateFilterPredicate( aliasGenerator, enabledFilters );
|
||||
if ( predicate != null ) {
|
||||
querySpec.applyPredicate( predicate );
|
||||
}
|
||||
}
|
||||
|
||||
public static FilterPredicate doCreateFilterPredicate(String filterFragment, Map<String, Filter> enabledFilters) {
|
||||
final Matcher matcher = FILTER_PARAMETER_PATTERN.matcher( filterFragment );
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
int pos = 0;
|
||||
final List<FilterJdbcParameter> 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<String, Filter> 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 ) );
|
||||
}
|
||||
if ( enabledFilter != null ) {
|
||||
String condition = render( aliasGenerator, i );
|
||||
|
||||
final List<String> 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 ) );
|
||||
}
|
||||
if ( parameterValue instanceof Iterable && !jdbcMapping.getJavaTypeDescriptor().isInstance( parameterValue ) ) {
|
||||
|
||||
final StringBuilder paramMarkers = new StringBuilder( "?" );
|
||||
if ( parameterValue instanceof Iterable
|
||||
&& !jdbcMapping.getJavaTypeDescriptor().isInstance( parameterValue ) ) {
|
||||
final Iterator<?> iterator = ( (Iterable<?>) parameterValue ).iterator();
|
||||
if ( iterator.hasNext() ) {
|
||||
parameters.add( new FilterJdbcParameter( jdbcMapping, iterator.next() ) );
|
||||
final Object value = iterator.next();
|
||||
final FilterJdbcParameter jdbcParameter = new FilterJdbcParameter( jdbcMapping, value );
|
||||
filterPredicate.applyParameter( jdbcParameter );
|
||||
|
||||
while ( iterator.hasNext() ) {
|
||||
sb.append( ",?" );
|
||||
parameters.add( new FilterJdbcParameter( jdbcMapping, iterator.next() ) );
|
||||
paramMarkers.append( ",?" );
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, iterator.next() ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need a dummy value if the list is empty
|
||||
parameters.add( new FilterJdbcParameter( jdbcMapping, null ) );
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, null ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
parameters.add( new FilterJdbcParameter( jdbcMapping, parameterValue ) );
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, parameterValue ) );
|
||||
}
|
||||
|
||||
final String marker = ":" + filterNames[ i ] + "." + parameterName;
|
||||
condition = condition.replaceAll( marker, paramMarkers.toString() );
|
||||
}
|
||||
|
||||
filterPredicate.applyFragment( condition );
|
||||
}
|
||||
}
|
||||
sb.append( filterFragment, pos, filterFragment.length() );
|
||||
return new FilterPredicate( sb.toString(), parameters );
|
||||
|
||||
if ( filterPredicate.isEmpty() ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return filterPredicate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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<String> treatAsDeclarations,
|
||||
Map<String, Filter> enabledFilters);
|
||||
}
|
||||
|
|
|
@ -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<String, Filter> enabledFilters,
|
||||
Set<String> 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<String, Filter> enabledFilters,
|
||||
Set<String> 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);
|
||||
}
|
||||
}
|
|
@ -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 <tt>QueryableCollection</tt> interface.
|
||||
|
@ -2036,47 +2041,71 @@ 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<String, Filter> enabledFilters,
|
||||
Set<String> 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<String, Filter> 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static TableGroupJoin findTableGroupJoin(TableGroup tableGroup, FromClauseAccess fromClauseAccess) {
|
||||
final NavigablePath parentNavigablePath;
|
||||
if ( tableGroup == null || ( parentNavigablePath = tableGroup.getNavigablePath().getParent() ) == null ) {
|
||||
return null;
|
||||
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 );
|
||||
|
@ -2088,6 +2117,37 @@ public abstract class AbstractCollectionPersister
|
|||
}
|
||||
}
|
||||
|
||||
assert pluralTableGroupJoin != null;
|
||||
pluralTableGroupJoin.applyPredicate( predicate );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected void applyFilterRestrictions(
|
||||
RestrictionPredicateConsumer predicateConsumer,
|
||||
TableGroup tableGroup,
|
||||
Map<String, Filter> enabledFilters,
|
||||
FromClauseAccess fromClauseAccess) {
|
||||
if ( filterHelper != null ) {
|
||||
filterHelper.applyFilters(
|
||||
getFilterAliasGenerator( tableGroup ),
|
||||
enabledFilters,
|
||||
(filterPredicate) -> predicateConsumer.consume( filterPredicate, COLLECTION, FILTER )
|
||||
);
|
||||
}
|
||||
|
||||
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<Predicate> 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<Predicate> 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<Predicate> 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 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
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,7 +1349,7 @@ 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 ] ) ) {
|
||||
|
@ -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<String, Filter> enabledFilters, Set<String> 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<String, Filter> enabledFilters,
|
||||
Set<String> 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<String, Filter> enabledFilters,
|
||||
Set<String> 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<String> treatAsDeclarations, Map<String, Filter> 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<String, Filter> 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 );
|
||||
FilterAliasGenerator aliasGenerator) {
|
||||
if ( filterHelper != null ) {
|
||||
filterHelper.applyFilters( querySpec, aliasGenerator, enabledFilters );
|
||||
}
|
||||
else {
|
||||
tableGroupJoin.applyPredicate( filterPredicate );
|
||||
}
|
||||
|
||||
protected void applyFilterRestrictions(
|
||||
Map<String, Filter> enabledFilters, FilterAliasGenerator aliasGenerator, Consumer<Predicate> predicateConsumer) {
|
||||
if ( filterHelper != null ) {
|
||||
filterHelper.applyFilters( aliasGenerator, enabledFilters, (Consumer) predicateConsumer );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4116,6 +4175,13 @@ public abstract class AbstractEntityPersister
|
|||
}
|
||||
}
|
||||
|
||||
protected void applyWhereRestriction(String alias, Set<String> treatAsDeclarations, Consumer<Predicate> 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;
|
||||
}
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
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<String, Filter> enabledFilters,
|
||||
Set<String> treatAsDeclarations,
|
||||
FromClauseAccess fromClauseAccess);
|
||||
|
||||
/**
|
||||
* Get the where clause filter, given a query alias and considering enabled session filters
|
||||
*/
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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<T extends Statement> extends Base
|
|||
private ForeignKeyDescriptor.Nature currentlyResolvingForeignKeySide;
|
||||
private SqmQueryPart<?> currentSqmQueryPart;
|
||||
|
||||
private Map<String, FilterPredicate> collectionFilterPredicates;
|
||||
private final Map<String, List<Predicate>> collectionFilterPredicates = new HashMap<>();
|
||||
private List<Map.Entry<OrderByFragment, TableGroup>> orderByFragments;
|
||||
|
||||
private final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager();
|
||||
|
@ -670,12 +687,11 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
final List<Assignment> 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<T extends Statement> 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<T extends Statement> 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) -> {
|
||||
root.getTableGroupJoins().forEach( (tableGroupJoin) -> {
|
||||
collectionFilterPredicates.forEach( (alias, predicates) -> {
|
||||
if ( tableGroupJoin.getJoinedGroup().getGroupAlias().equals( alias ) ) {
|
||||
tableGroupJoin.applyPredicate( predicate );
|
||||
if ( CollectionHelper.isNotEmpty( predicates ) ) {
|
||||
predicates.forEach( tableGroupJoin::applyPredicate );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
);
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2319,14 +2329,15 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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<T extends Statement> 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,31 +5675,14 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> 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<>();
|
||||
|
||||
( (Restrictable) pluralAttributeMapping.getCollectionDescriptor() ).applyRestrictions(
|
||||
(predicate, partType, sourceType) -> {
|
||||
if ( partType == RestrictionPredicatePartType.COLLECTION ) {
|
||||
addCollectionFilterPredicate( tableGroup.getGroupAlias(), predicate );
|
||||
}
|
||||
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 ) {
|
||||
else if ( partType == RestrictionPredicatePartType.MANY_TO_MANY ) {
|
||||
final TableGroup parentTableGroup = getFromClauseIndex().getTableGroup( fetchParent.getNavigablePath() );
|
||||
TableGroupJoin pluralTableGroupJoin = null;
|
||||
for ( TableGroupJoin nestedTableGroupJoin : parentTableGroup.getTableGroupJoins() ) {
|
||||
|
@ -5696,9 +5693,18 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
|
|||
}
|
||||
|
||||
assert pluralTableGroupJoin != null;
|
||||
pluralTableGroupJoin.applyPredicate( manyToManyFilterPredicate );
|
||||
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<T extends Statement> extends Base
|
|||
}
|
||||
}
|
||||
|
||||
private void addCollectionFilterPredicate(String groupAlias, Predicate predicate) {
|
||||
final List<Predicate> existing = collectionFilterPredicates.get( groupAlias );
|
||||
if ( existing != null ) {
|
||||
existing.add( predicate );
|
||||
}
|
||||
else {
|
||||
final ArrayList<Predicate> 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() );
|
||||
|
|
|
@ -157,6 +157,7 @@ public interface SqlAstWalker {
|
|||
void visitBetweenPredicate(BetweenPredicate betweenPredicate);
|
||||
|
||||
void visitFilterPredicate(FilterPredicate filterPredicate);
|
||||
void visitFilterFragmentPredicate(FilterPredicate.FilterFragmentPredicate fragmentPredicate);
|
||||
|
||||
void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate);
|
||||
|
||||
|
|
|
@ -4279,14 +4279,22 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
@Override
|
||||
public void visitFilterPredicate(FilterPredicate filterPredicate) {
|
||||
assert StringHelper.isNotEmpty( filterPredicate.getFilterFragment() );
|
||||
appendSql( filterPredicate.getFilterFragment() );
|
||||
for ( FilterJdbcParameter filterJdbcParameter : filterPredicate.getFilterJdbcParameters() ) {
|
||||
visitJunction( filterPredicate.getFragments() );
|
||||
|
||||
final List<FilterJdbcParameter> 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) {
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
|
|
@ -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<FilterJdbcParameter> filterJdbcParameters;
|
||||
private Junction fragments = new Junction();
|
||||
private List<FilterJdbcParameter> parameters;
|
||||
|
||||
public FilterPredicate(String filterFragment, List<FilterJdbcParameter> 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<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return filterJdbcParameters;
|
||||
public List<FilterJdbcParameter> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,10 @@ public class Junction implements Predicate {
|
|||
private final JdbcMappingContainer expressionType;
|
||||
private final List<Predicate> predicates = new ArrayList<>();
|
||||
|
||||
public Junction() {
|
||||
this( Nature.CONJUNCTION );
|
||||
}
|
||||
|
||||
public Junction(Nature nature) {
|
||||
this( nature, null );
|
||||
}
|
||||
|
|
|
@ -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<String> treatAsDeclarations, Map<String, Filter> enabledFilters) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NoopCollectionPersister implements CollectionPersister {
|
||||
|
|
|
@ -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<String> treatAsDeclarations, Map<String, Filter> enabledFilters) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GoofyException extends RuntimeException {
|
||||
|
|
|
@ -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<String> treatAsDeclarations, Map<String, Filter> enabledFilters) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue