HHH-14977 - @Where is broken in 6.0

Next iteration where `@Where` fragments generate AST one or more `WhereFilterPredicate` instances.

At the moment, `@Filter` fragments are collected together using the existing String-manipulation style and still collected into a single `FilterPredicate`.  Next step is to make that more AST-centric and hopefully get rid of the String-manip-based methods
This commit is contained in:
Steve Ebersole 2021-12-15 10:49:30 -06:00
parent c5c24344a4
commit 579b3f0dcb
12 changed files with 382 additions and 82 deletions

View File

@ -16,13 +16,11 @@
import org.hibernate.Filter;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.FilterDefinition;
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.AbstractCollectionPersister;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.sql.Template;
@ -163,6 +161,33 @@ public static FilterPredicate createFilterPredicate(
return createFilterPredicate( loadQueryInfluencers, joinable, rootTableGroup, true );
}
public static FilterPredicate createFilterPredicate(
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,
@ -193,7 +218,7 @@ public static FilterPredicate createManyToManyFilterPredicate(LoadQueryInfluence
}
}
private static FilterPredicate doCreateFilterPredicate(String filterFragment, Map<String, Filter> enabledFilters) {
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;

View File

@ -10,7 +10,6 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -21,16 +20,15 @@
import org.hibernate.collection.spi.BagSemantics;
import org.hibernate.engine.FetchStyle;
import org.hibernate.engine.FetchTiming;
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.engine.profile.FetchProfile;
import org.hibernate.engine.spi.CascadeStyle;
import org.hibernate.engine.spi.CascadingAction;
import org.hibernate.engine.spi.EffectiveEntityGraph;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.graph.GraphSemantic;
import org.hibernate.graph.spi.RootGraphImplementor;
import org.hibernate.internal.FilterHelper;
import org.hibernate.loader.ast.spi.Loadable;
import org.hibernate.loader.ast.spi.Loader;
import org.hibernate.metamodel.mapping.AttributeMapping;
@ -70,7 +68,6 @@
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.select.QueryPart;
import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SelectStatement;
@ -480,7 +477,7 @@ private SelectStatement generateSelect() {
applyOrdering( rootTableGroup, pluralAttributeMapping );
}
else if ( loadable instanceof Joinable ) {
applyFiltering( rootQuerySpec, rootTableGroup, (Joinable) loadable );
applyFiltering( rootQuerySpec, rootTableGroup, (Joinable) loadable, sqlAstCreationState.getFromClauseAccess() );
}
if ( orderByFragments != null ) {
@ -589,57 +586,30 @@ private void applyFiltering(
PluralAttributeMapping pluralAttributeMapping,
FromClauseAccess fromClauseAccess) {
final CollectionPersister collectionPersister = pluralAttributeMapping.getCollectionDescriptor();
final Joinable joinable = collectionPersister.getCollectionType()
.getAssociatedJoinable( creationContext.getSessionFactory() );
final Predicate filterPredicate = FilterHelper.createFilterPredicate(
loadQueryInfluencers,
joinable,
tableGroup
final Joinable joinable = collectionPersister.getCollectionType().getAssociatedJoinable( creationContext.getSessionFactory() );
joinable.applyRestrictions(
querySpec,
tableGroup,
true,
loadQueryInfluencers.getEnabledFilters(),
null,
fromClauseAccess
);
if ( filterPredicate != null ) {
querySpec.applyPredicate( filterPredicate );
}
if ( collectionPersister.isManyToMany() ) {
assert joinable instanceof CollectionPersister;
final Predicate manyToManyFilterPredicate = FilterHelper.createManyToManyFilterPredicate(
loadQueryInfluencers,
(CollectionPersister) joinable,
tableGroup
);
if ( manyToManyFilterPredicate != null ) {
final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent();
if ( parentNavigablePath == null ) {
querySpec.applyPredicate( manyToManyFilterPredicate );
}
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( manyToManyFilterPredicate );
}
}
}
}
private void applyFiltering(
QuerySpec querySpec,
TableGroup tableGroup,
Joinable joinable) {
final Predicate filterPredicate = FilterHelper.createFilterPredicate(
loadQueryInfluencers,
joinable,
tableGroup
Joinable joinable,
FromClauseAccess fromClauseAccess) {
joinable.applyRestrictions(
querySpec,
tableGroup,
true,
loadQueryInfluencers.getEnabledFilters(),
null,
fromClauseAccess
);
if ( filterPredicate != null ) {
querySpec.applyPredicate( filterPredicate );
}
}
private void applyOrdering(TableGroup tableGroup, PluralAttributeMapping pluralAttributeMapping) {

View File

@ -37,9 +37,7 @@
import org.hibernate.collection.spi.CollectionSemantics;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.dialect.Dialect;
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.engine.jdbc.batch.internal.BasicBatchKey;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.engine.profile.Fetch;
@ -50,6 +48,7 @@
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.exception.spi.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.internal.CoreMessageLogger;
@ -88,6 +87,7 @@
import org.hibernate.persister.entity.Joinable;
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.walking.internal.CompositionSingularSubAttributesHelper;
import org.hibernate.persister.walking.internal.StandardAnyTypeDefinition;
@ -110,13 +110,16 @@
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
import org.hibernate.sql.Update;
import org.hibernate.sql.ast.spi.FromClauseAccess;
import org.hibernate.sql.ast.spi.SimpleFromClauseAccessImpl;
import org.hibernate.sql.ast.spi.SqlAliasBaseConstant;
import org.hibernate.sql.ast.spi.SqlAliasBaseManager;
import org.hibernate.sql.ast.spi.SqlSelection;
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.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SelectClause;
import org.hibernate.sql.ast.tree.select.SelectStatement;
@ -131,6 +134,8 @@
import org.jboss.logging.Logger;
import static org.hibernate.internal.FilterHelper.doCreateFilterPredicate;
/**
* Base implementation of the <tt>QueryableCollection</tt> interface.
*
@ -617,14 +622,12 @@ else if ( !elementType.isEntityType() ) {
);
}
else {
if ( elementPersister instanceof PropertyMapping ) { // not all classpersisters implement PropertyMapping!
// not all entity-persisters implement PropertyMapping!
if ( elementPersister instanceof PropertyMapping ) {
elementPropertyMapping = (PropertyMapping) elementPersister;
}
else {
elementPropertyMapping = new ElementPropertyMapping(
elementColumnNames,
elementType
);
elementPropertyMapping = new ElementPropertyMapping( elementColumnNames, elementType );
}
}
@ -632,16 +635,33 @@ else if ( !elementType.isEntityType() ) {
hasManyToManyOrder = collectionBootDescriptor.getManyToManyOrdering() != null;
// Handle any filters applied to this collectionBinding
filterHelper = new FilterHelper( collectionBootDescriptor.getFilters(), factory);
if ( collectionBootDescriptor.getFilters().isEmpty() ) {
filterHelper = null;
}
else {
filterHelper = new FilterHelper( collectionBootDescriptor.getFilters(), factory);
}
// Handle any filters applied to this collectionBinding for many-to-many
manyToManyFilterHelper = new FilterHelper( collectionBootDescriptor.getManyToManyFilters(), factory);
manyToManyWhereString = StringHelper.isNotEmpty( collectionBootDescriptor.getManyToManyWhere() ) ?
"( " + collectionBootDescriptor.getManyToManyWhere() + ")" :
null;
manyToManyWhereTemplate = manyToManyWhereString == null ?
null :
Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getQueryEngine().getSqmFunctionRegistry() );
if ( collectionBootDescriptor.getManyToManyFilters().isEmpty() ) {
manyToManyFilterHelper = null;
}
else {
manyToManyFilterHelper = new FilterHelper( collectionBootDescriptor.getManyToManyFilters(), factory);
}
if ( StringHelper.isEmpty( collectionBootDescriptor.getManyToManyWhere() ) ) {
manyToManyWhereString = null;
manyToManyWhereTemplate = null;
}
else {
manyToManyWhereString = "( " + collectionBootDescriptor.getManyToManyWhere() + ")";
manyToManyWhereTemplate = Template.renderWhereStringTemplate(
manyToManyWhereString,
factory.getJdbcServices().getDialect(),
factory.getQueryEngine().getSqmFunctionRegistry()
);
}
comparator = collectionBootDescriptor.getComparator();
@ -1825,19 +1845,24 @@ public Type toType(String propertyName) throws QueryException {
@Override
public String getManyToManyFilterFragment(TableGroup tableGroup, Map<String, Filter> enabledFilters) {
StringBuilder buffer = new StringBuilder();
manyToManyFilterHelper.render( buffer, elementPersister.getFilterAliasGenerator( tableGroup ), enabledFilters );
assert elementPersister instanceof Joinable;
if ( manyToManyWhereString != null ) {
if ( buffer.length() > 0 ) {
buffer.append( " and " );
}
assert elementPersister instanceof Joinable;
final TableReference tableReference = tableGroup.resolveTableReference( ( (Joinable) elementPersister ).getTableName() );
buffer.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, tableReference.getIdentificationVariable() ) );
final StringBuilder fragment = new StringBuilder();
if ( manyToManyFilterHelper != null ) {
assert isManyToMany();
manyToManyFilterHelper.render( fragment, elementPersister.getFilterAliasGenerator( tableGroup ), enabledFilters );
}
return buffer.toString();
if ( manyToManyWhereString != null ) {
if ( fragment.length() > 0 ) {
fragment.append( " and " );
}
final TableReference tableReference = tableGroup.resolveTableReference( ( (Joinable) elementPersister ).getTableName() );
fragment.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, tableReference.getIdentificationVariable() ) );
}
return fragment.toString();
}
private String[] indexFragments;
@ -1963,14 +1988,146 @@ protected String filterFragment(String alias, Set<String> treatAsDeclarations) t
return hasWhere() ? getSQLWhereString( alias ) : "";
}
/**
* Apply both {@link org.hibernate.annotations.Filter} and
* {@link org.hibernate.annotations.Where} restrictions
*/
@Override
public void applyRestrictions(
QuerySpec querySpec,
TableGroup tableGroup,
boolean useQualifier,
Map<String, Filter> enabledFilters,
Set<String> treatAsDeclarations,
FromClauseAccess fromClauseAccess) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// handle `@Filter`
applyFilterRestrictions( querySpec, tableGroup, enabledFilters, fromClauseAccess );
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// handle `@Where`
TableReference tableReference;
if ( isManyToMany() ) {
// if filtering on many-to-many element were intended, getManyToManyFilterFragmentgetManyToManyFilterFragment() should have been chosen
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, querySpec );
applyManyToManyWhereRestriction( tableGroup, querySpec );
applyOneToManyWhereRestriction( alias, tableGroup, querySpec );
}
protected void applyFilterRestrictions(
QuerySpec querySpec,
TableGroup tableGroup,
Map<String, Filter> enabledFilters,
FromClauseAccess fromClauseAccess) {
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 );
querySpec.applyPredicate( filterPredicate );
}
}
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 );
final NavigablePath parentNavigablePath = tableGroup.getNavigablePath().getParent();
if ( parentNavigablePath == null ) {
querySpec.applyPredicate( filterPredicate );
}
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( filterPredicate );
}
}
}
}
protected void applyWhereRestriction(String alias, QuerySpec querySpec) {
if ( sqlWhereString != null ) {
final String whereCondition = getSQLWhereString( alias );
assert whereCondition != null;
querySpec.applyPredicate( new WhereFilterPredicate( whereCondition ) );
}
}
public void applyManyToManyWhereRestriction(TableGroup tableGroup, QuerySpec querySpec) {
if ( manyToManyWhereString == null ) {
return;
}
final TableReference tableReference = tableGroup.resolveTableReference( ( (Joinable) elementPersister ).getTableName() );
final String condition = StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, tableReference.getIdentificationVariable() );
assert StringHelper.isNotEmpty( condition );
querySpec.applyPredicate( new WhereFilterPredicate( condition ) );
}
private void applyOneToManyWhereRestriction(String alias, TableGroup tableGroup, QuerySpec querySpec) {
if ( ! isOneToMany() ) {
return;
}
if ( ! ( getElementPersister() instanceof Joinable ) ) {
return;
}
final String associationWhereCondition = ( (Joinable) getElementPersister() ).oneToManyFilterFragment( alias, null );
if ( StringHelper.isNotEmpty( associationWhereCondition ) ) {
querySpec.applyPredicate( new WhereFilterPredicate( associationWhereCondition ) );
}
}
@Override
public String filterFragment(
String alias,
Map<String, Filter> enabledFilters,
Set<String> treatAsDeclarations) {
StringBuilder sessionFilterFragment = new StringBuilder();
filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters );
// actual `@Filter`
if ( filterHelper != null ) {
filterHelper.render( sessionFilterFragment, getFilterAliasGenerator(alias), enabledFilters );
}
// `@Where` - poorly named
final String filterFragment = filterFragment( alias, treatAsDeclarations );
if ( sessionFilterFragment.length() != 0 && !filterFragment.isEmpty() ) {
sessionFilterFragment.append( " and " );
}
@ -2006,8 +2163,15 @@ else if ( useIdentificationVariable && tableReference.getIdentificationVariable(
alias = tableReference.getTableExpression();
}
StringBuilder sessionFilterFragment = new StringBuilder();
filterHelper.render( sessionFilterFragment, getFilterAliasGenerator( tableGroup ), enabledFilters );
// `@Filter
if ( filterHelper != null ) {
filterHelper.render( sessionFilterFragment, getFilterAliasGenerator( tableGroup ), enabledFilters );
}
// `@Where`
final String filterFragment = filterFragment( alias, treatAsDeclarations );
if ( sessionFilterFragment.length() != 0 && !filterFragment.isEmpty() ) {
sessionFilterFragment.append( " and " );
}
@ -2446,8 +2610,8 @@ public PluralAttributeMapping getAttributeMapping() {
public boolean isAffectedByEnabledFilters(LoadQueryInfluencers influencers) {
if ( influencers.hasEnabledFilters() ) {
final Map<String, Filter> enabledFilters = influencers.getEnabledFilters();
return filterHelper.isAffectedBy( enabledFilters ) ||
( isManyToMany() && manyToManyFilterHelper.isAffectedBy( enabledFilters ) );
return ( filterHelper != null && filterHelper.isAffectedBy( enabledFilters ) )
|| ( manyToManyFilterHelper != null && manyToManyFilterHelper.isAffectedBy( enabledFilters ) );
}
return false;

View File

@ -109,6 +109,7 @@
import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
import org.hibernate.internal.CoreLogging;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.FilterAliasGenerator;
import org.hibernate.internal.FilterHelper;
import org.hibernate.internal.util.LazyValue;
import org.hibernate.internal.util.StringHelper;
@ -191,6 +192,7 @@
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.persister.spi.PersisterCreationContext;
import org.hibernate.persister.walking.internal.EntityIdentifierDefinitionHelper;
import org.hibernate.persister.walking.spi.AttributeDefinition;
@ -232,6 +234,7 @@
import org.hibernate.sql.ast.tree.from.TableReference;
import org.hibernate.sql.ast.tree.from.TableReferenceJoin;
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
import org.hibernate.sql.ast.tree.predicate.FilterPredicate;
import org.hibernate.sql.ast.tree.predicate.Junction;
import org.hibernate.sql.ast.tree.predicate.Predicate;
import org.hibernate.sql.ast.tree.select.QuerySpec;
@ -264,6 +267,8 @@
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
@ -4020,6 +4025,62 @@ else if ( useIdentificationVariable && tableGroup.getPrimaryTableReference().get
return sessionFilterFragment.append( filterFragment ).toString();
}
public String generateWhereConditionAlias(String alias) {
return alias;
}
/**
* Apply both {@link org.hibernate.annotations.Filter} and
* {@link org.hibernate.annotations.Where} restrictions
*/
@Override
public void applyRestrictions(
QuerySpec querySpec,
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( querySpec, tableGroup, enabledFilters, aliasGenerator );
// 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, querySpec );
}
protected void applyFilterRestrictions(
QuerySpec querySpec,
TableGroup tableGroup,
Map<String, Filter> enabledFilters,
FilterAliasGenerator aliasGenerator) {
final StringBuilder fragment = new StringBuilder();
filterHelper.render( fragment, aliasGenerator, enabledFilters );
if ( fragment.length() > 1 ) {
final FilterPredicate filterPredicate = doCreateFilterPredicate( fragment.toString(), enabledFilters );
querySpec.applyPredicate( filterPredicate );
}
}
protected void applyWhereRestriction(String alias, Set<String> treatAsDeclarations, QuerySpec querySpec) {
if ( hasWhere() ) {
final String whereCondition = getSQLWhereString( alias );
querySpec.applyPredicate( new WhereFilterPredicate( whereCondition ) );
}
}
public String generateFilterConditionAlias(String rootAlias) {
return rootAlias;
}

View File

@ -11,7 +11,9 @@
import org.hibernate.Filter;
import org.hibernate.MappingException;
import org.hibernate.sql.ast.spi.FromClauseAccess;
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
@ -36,6 +38,18 @@ 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
*/

View File

@ -974,6 +974,10 @@ public String generateFilterConditionAlias(String rootAlias) {
return generateTableAlias( rootAlias, tableSpan - 1 );
}
public String generateWhereConditionAlias(String rootAlias) {
return generateTableAlias( rootAlias, tableSpan - 1 );
}
public String[] getIdentifierColumnNames() {
return tableKeyColumns[0];
}

View File

@ -0,0 +1,42 @@
/*
* 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.persister.internal;
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.predicate.Predicate;
/**
* Models a Predicate for {@link org.hibernate.annotations.Where}
*/
public class WhereFilterPredicate implements Predicate {
private final String whereCondition;
public WhereFilterPredicate(String whereCondition) {
this.whereCondition = whereCondition;
}
public String getWhereCondition() {
return whereCondition;
}
@Override
public void accept(SqlAstWalker sqlTreeWalker) {
sqlTreeWalker.visitWhereFilterPredicate( this );
}
@Override
public JdbcMappingContainer getExpressionType() {
return null;
}
@Override
public boolean isEmpty() {
return false;
}
}

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.ast;
import org.hibernate.Incubating;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.query.sqm.tree.expression.Conversion;
import org.hibernate.sql.ast.spi.SqlSelection;
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
@ -157,6 +158,8 @@ public interface SqlAstWalker {
void visitFilterPredicate(FilterPredicate filterPredicate);
void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate);
void visitGroupedPredicate(GroupedPredicate groupedPredicate);
void visitInListPredicate(InListPredicate inListPredicate);

View File

@ -33,6 +33,7 @@
import org.hibernate.metamodel.mapping.ModelPart;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Queryable;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.query.IllegalQueryOperationException;
import org.hibernate.query.sqm.sql.internal.SqmPathInterpretation;
import org.hibernate.sql.ast.tree.cte.CteMaterialization;
@ -4287,6 +4288,12 @@ public void visitFilterPredicate(FilterPredicate filterPredicate) {
}
}
@Override
public void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate) {
assert StringHelper.isNotEmpty( whereFilterPredicate.getWhereCondition() );
appendSql( whereFilterPredicate.getWhereCondition() );
}
@Override
public void visitGroupedPredicate(GroupedPredicate groupedPredicate) {
if ( groupedPredicate.isEmpty() ) {

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.ast.spi;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.query.sqm.tree.expression.Conversion;
import org.hibernate.sql.ast.SqlAstWalker;
import org.hibernate.sql.ast.tree.SqlAstNode;
@ -446,6 +447,10 @@ public void visitDurationUnit(DurationUnit durationUnit) {
public void visitFilterPredicate(FilterPredicate filterPredicate) {
}
@Override
public void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate) {
}
@Override
public void visitParameter(JdbcParameter jdbcParameter) {
}

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.ast.spi;
import org.hibernate.persister.internal.WhereFilterPredicate;
import org.hibernate.query.sqm.tree.expression.Conversion;
import org.hibernate.sql.ast.tree.SqlAstNode;
import org.hibernate.sql.ast.tree.delete.DeleteStatement;
@ -205,6 +206,10 @@ public void visitExistsPredicate(ExistsPredicate existsPredicate) {
public void visitFilterPredicate(FilterPredicate filterPredicate) {
}
@Override
public void visitWhereFilterPredicate(WhereFilterPredicate whereFilterPredicate) {
}
@Override
public void visitParameter(JdbcParameter jdbcParameter) {
}

View File

@ -71,7 +71,7 @@ public static class EntityA {
@OneToMany
@JoinColumn(name = "allC")
@Where(clause = "TYPE = 'C'")
@Where(clause = "type = 'C'")
private Set<EntityC> allMyC;
public Integer getId() {