mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-16 16:15:06 +00:00
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:
parent
c5c24344a4
commit
579b3f0dcb
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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() ) {
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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) {
|
||||
}
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user