HHH-16260 - JdbcParameterRenderer not called with dynamic filters
This commit is contained in:
parent
c86d755d75
commit
07a653aa50
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -15,13 +14,10 @@ import java.util.regex.Matcher;
|
|||
import java.util.regex.Pattern;
|
||||
|
||||
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.metamodel.mapping.Restrictable;
|
||||
import org.hibernate.sql.Template;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
|
@ -163,48 +159,7 @@ public class FilterHelper {
|
|||
final String filterName = filterNames[i];
|
||||
final FilterImpl enabledFilter = (FilterImpl) enabledFilters.get( filterName );
|
||||
if ( enabledFilter != null ) {
|
||||
String condition = render( aliasGenerator, i );
|
||||
final List<String> filterParameterNames = parameterNames[i];
|
||||
if ( CollectionHelper.isNotEmpty( filterParameterNames ) ) {
|
||||
for ( int paramPos = 0; paramPos < filterParameterNames.size(); paramPos++ ) {
|
||||
final String parameterName = filterParameterNames.get( paramPos );
|
||||
final FilterDefinition filterDefinition = enabledFilter.getFilterDefinition();
|
||||
final JdbcMapping jdbcMapping = filterDefinition.getParameterJdbcMapping( parameterName );
|
||||
final Object parameterValue = enabledFilter.getParameter( parameterName );
|
||||
if ( parameterValue == null ) {
|
||||
throw new MappingException( String.format( "unknown parameter [%s] for filter [%s]", parameterName, filterName ) );
|
||||
}
|
||||
|
||||
final StringBuilder paramMarkers = new StringBuilder( "?" );
|
||||
if ( parameterValue instanceof Iterable
|
||||
&& !jdbcMapping.getJavaTypeDescriptor().isInstance( parameterValue ) ) {
|
||||
final Iterator<?> iterator = ( (Iterable<?>) parameterValue ).iterator();
|
||||
if ( iterator.hasNext() ) {
|
||||
final Object element = iterator.next();
|
||||
final FilterJdbcParameter jdbcParameter = new FilterJdbcParameter( jdbcMapping, element );
|
||||
filterPredicate.applyParameter( jdbcParameter );
|
||||
|
||||
while ( iterator.hasNext() ) {
|
||||
paramMarkers.append( ",?" );
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, iterator.next() ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need a dummy value if the list is empty
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, null ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Object argument = filterDefinition.processArgument( parameterValue );
|
||||
filterPredicate.applyParameter( new FilterJdbcParameter( jdbcMapping, argument) );
|
||||
}
|
||||
|
||||
final String marker = ":" + filterNames[ i ] + "." + parameterName;
|
||||
condition = condition.replaceAll( marker, paramMarkers.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
filterPredicate.applyFragment( condition );
|
||||
filterPredicate.applyFragment( render( aliasGenerator, i ), enabledFilter, parameterNames[i] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,65 +6,52 @@
|
|||
*/
|
||||
package org.hibernate.internal;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterBindingImpl;
|
||||
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
|
||||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
|
||||
/**
|
||||
* @author Nathan Xu
|
||||
*/
|
||||
public class FilterJdbcParameter {
|
||||
private final JdbcParameter parameter;
|
||||
public class FilterJdbcParameter implements JdbcParameter, JdbcParameterBinder {
|
||||
private final JdbcMapping jdbcMapping;
|
||||
private final Object jdbcParameterValue;
|
||||
|
||||
public FilterJdbcParameter(JdbcMapping jdbcMapping, Object jdbcParameterValue) {
|
||||
this.parameter = new JdbcParameterImpl( jdbcMapping );
|
||||
this.jdbcMapping = jdbcMapping;
|
||||
this.jdbcParameterValue = jdbcParameterValue;
|
||||
}
|
||||
|
||||
public JdbcParameter getParameter() {
|
||||
return parameter;
|
||||
}
|
||||
|
||||
public JdbcParameterBinder getBinder() {
|
||||
return parameter.getParameterBinder();
|
||||
}
|
||||
|
||||
public JdbcParameterBinding getBinding() {
|
||||
return new JdbcParameterBindingImpl( jdbcMapping, jdbcMapping.convertToRelationalValue( jdbcParameterValue ) );
|
||||
@Override
|
||||
public JdbcParameterBinder getParameterBinder() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if ( this == o ) {
|
||||
return true;
|
||||
}
|
||||
if ( o == null || getClass() != o.getClass() ) {
|
||||
return false;
|
||||
}
|
||||
FilterJdbcParameter that = (FilterJdbcParameter) o;
|
||||
return Objects.equals( parameter, that.parameter ) &&
|
||||
Objects.equals( jdbcMapping, that.jdbcMapping ) &&
|
||||
( (JavaType<Object>) jdbcMapping.getMappedJavaType() ).areEqual(
|
||||
jdbcParameterValue,
|
||||
that.jdbcParameterValue
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(
|
||||
parameter,
|
||||
jdbcMapping,
|
||||
( (JavaType<Object>) jdbcMapping.getMappedJavaType() ).extractHashCode( jdbcParameterValue )
|
||||
public void bindParameterValue(PreparedStatement statement, int startPosition, JdbcParameterBindings jdbcParameterBindings, ExecutionContext executionContext) throws SQLException {
|
||||
jdbcMapping.getJdbcValueBinder().bind(
|
||||
statement,
|
||||
jdbcMapping.convertToRelationalValue( jdbcParameterValue ),
|
||||
startPosition,
|
||||
executionContext.getSession()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public JdbcMappingContainer getExpressionType() {
|
||||
return jdbcMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||
throw new IllegalStateException( );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,6 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
|
|||
.translate( null, QueryOptions.NONE );
|
||||
|
||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( keyJdbcCount * smallBatchLength );
|
||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
|
||||
int offset = 0;
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
|
|||
assert jdbcParameters.size() % jdbcTypeCount == 0;
|
||||
|
||||
final JdbcParameterBindings jdbcParameterBindings = new JdbcParameterBindingsImpl( jdbcTypeCount );
|
||||
jdbcSelect.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
|
||||
int offset = 0;
|
||||
while ( offset < jdbcParameters.size() ) {
|
||||
|
|
|
@ -304,7 +304,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
|
|||
|
||||
private JdbcParameterBindings createJdbcParameterBindings(CacheableSqmInterpretation sqmInterpretation, DomainQueryExecutionContext executionContext) {
|
||||
final SharedSessionContractImplementor session = executionContext.getSession();
|
||||
final JdbcParameterBindings jdbcParameterBindings = SqmUtil.createJdbcParameterBindings(
|
||||
return SqmUtil.createJdbcParameterBindings(
|
||||
executionContext.getQueryParameterBindings(),
|
||||
domainParameterXref,
|
||||
sqmInterpretation.getJdbcParamsXref(),
|
||||
|
@ -319,8 +319,6 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
|
|||
},
|
||||
session
|
||||
);
|
||||
sqmInterpretation.getJdbcSelect().bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
return jdbcParameterBindings;
|
||||
}
|
||||
|
||||
private static CacheableSqmInterpretation buildCacheableSqmInterpretation(
|
||||
|
|
|
@ -123,9 +123,6 @@ public class SimpleDeleteQueryPlan implements NonSelectQueryPlan {
|
|||
if ( deleteTranslator != null ) {
|
||||
jdbcDelete = deleteTranslator.translate( jdbcParameterBindings, executionContext.getQueryOptions() );
|
||||
}
|
||||
else {
|
||||
jdbcDelete.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
}
|
||||
|
||||
final boolean missingRestriction = sqmDelete.getWhereClause() == null
|
||||
|| sqmDelete.getWhereClause().getPredicate() == null;
|
||||
|
|
|
@ -117,9 +117,6 @@ public class SimpleInsertQueryPlan implements NonSelectQueryPlan {
|
|||
if ( insertTranslator != null ) {
|
||||
jdbcInsert = insertTranslator.translate( jdbcParameterBindings, executionContext.getQueryOptions() );
|
||||
}
|
||||
else {
|
||||
jdbcInsert.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
}
|
||||
|
||||
return jdbcServices.getJdbcMutationExecutor().execute(
|
||||
jdbcInsert,
|
||||
|
|
|
@ -86,9 +86,6 @@ public class SimpleUpdateQueryPlan implements NonSelectQueryPlan {
|
|||
if ( updateTranslator != null ) {
|
||||
jdbcUpdate = updateTranslator.translate( jdbcParameterBindings, executionContext.getQueryOptions() );
|
||||
}
|
||||
else {
|
||||
jdbcUpdate.bindFilterJdbcParameters( jdbcParameterBindings );
|
||||
}
|
||||
|
||||
return jdbcServices.getJdbcMutationExecutor().execute(
|
||||
jdbcUpdate,
|
||||
|
|
|
@ -149,6 +149,8 @@ import org.hibernate.sql.ast.tree.predicate.BooleanExpressionPredicate;
|
|||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.ExistsPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.FilterPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.FilterPredicate.FilterFragmentParameter;
|
||||
import org.hibernate.sql.ast.tree.predicate.FilterPredicate.FilterFragmentPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.GroupedPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.InListPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.InSubQueryPredicate;
|
||||
|
@ -273,9 +275,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
private final JdbcParameterRenderer jdbcParameterRenderer;
|
||||
|
||||
|
||||
|
||||
private final Set<FilterJdbcParameter> filterJdbcParameters = new HashSet<>();
|
||||
|
||||
private final Stack<Clause> clauseStack = new StandardStack<>( Clause.class );
|
||||
private final Stack<QueryPart> queryPartStack = new StandardStack<>( QueryPart.class );
|
||||
private final Stack<Statement> statementStack = new StandardStack<>( Statement.class );
|
||||
|
@ -455,10 +454,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
}
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
public Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return filterJdbcParameters;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected SqlAppender getSqlAppender() {
|
||||
return this;
|
||||
|
@ -786,15 +781,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
throw new IllegalArgumentException( "Unexpected statement - " + statement );
|
||||
}
|
||||
|
||||
if ( jdbcParameterBindings != null && CollectionHelper.isNotEmpty( getFilterJdbcParameters() ) ) {
|
||||
for ( FilterJdbcParameter filterJdbcParameter : getFilterJdbcParameters() ) {
|
||||
jdbcParameterBindings.addBinding(
|
||||
filterJdbcParameter.getParameter(),
|
||||
filterJdbcParameter.getBinding()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection unchecked
|
||||
return (T) jdbcOperation;
|
||||
}
|
||||
|
@ -810,7 +796,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
getSql(),
|
||||
getParameterBinders(),
|
||||
getAffectedTableNames(),
|
||||
getFilterJdbcParameters(),
|
||||
getAppliedParameterBindings()
|
||||
);
|
||||
}
|
||||
|
@ -822,7 +807,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
getSql(),
|
||||
getParameterBinders(),
|
||||
getAffectedTableNames(),
|
||||
getFilterJdbcParameters(),
|
||||
getAppliedParameterBindings()
|
||||
);
|
||||
}
|
||||
|
@ -849,7 +833,6 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
getParameterBinders(),
|
||||
buildJdbcValuesMappingProducer( selectStatement ),
|
||||
getAffectedTableNames(),
|
||||
getFilterJdbcParameters(),
|
||||
rowsToSkip = getRowsToSkip( selectStatement, getJdbcParameterBindings() ),
|
||||
getMaxRows( selectStatement, getJdbcParameterBindings(), rowsToSkip ),
|
||||
getAppliedParameterBindings(),
|
||||
|
@ -6653,21 +6636,70 @@ public abstract class AbstractSqlAstTranslator<T extends JdbcOperation> implemen
|
|||
|
||||
@Override
|
||||
public void visitFilterPredicate(FilterPredicate filterPredicate) {
|
||||
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 );
|
||||
// visits each fragment with " and " between them
|
||||
final List<FilterFragmentPredicate> filters = filterPredicate.getFragments();
|
||||
for ( int i = 0; i < filters.size(); i++ ) {
|
||||
final FilterFragmentPredicate filter = filters.get( i );
|
||||
visitFilterFragmentPredicate( filter );
|
||||
if ( i + 1 < filters.size() ) {
|
||||
appendSql( " and " );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitFilterFragmentPredicate(FilterPredicate.FilterFragmentPredicate fragmentPredicate) {
|
||||
appendSql( fragmentPredicate.getSqlFragment() );
|
||||
public void visitFilterFragmentPredicate(FilterFragmentPredicate filter) {
|
||||
// process a specific filter
|
||||
final String sqlFragment = filter.getSqlFragment();
|
||||
|
||||
if ( filter.getParameters() == null ) {
|
||||
sqlBuffer.append( sqlFragment );
|
||||
return;
|
||||
}
|
||||
|
||||
int lastEnd = 0;
|
||||
for ( int p = 0; p < filter.getParameters().size(); p++ ) {
|
||||
final FilterFragmentParameter parameter = filter.getParameters().get( p );
|
||||
lastEnd = processFilterParameter( parameter, sqlFragment, lastEnd );
|
||||
}
|
||||
|
||||
if ( lastEnd < sqlFragment.length() ) {
|
||||
appendSql( sqlFragment.substring( lastEnd ) );
|
||||
}
|
||||
}
|
||||
|
||||
private int processFilterParameter(FilterFragmentParameter parameter, String sqlFragment, int startPosition) {
|
||||
final String marker = ":" + parameter.getFilterName() + "." + parameter.getParameterName();
|
||||
final int markerStart = sqlFragment.indexOf( marker, startPosition );
|
||||
|
||||
appendSql( sqlFragment.substring( startPosition, markerStart ) );
|
||||
|
||||
final Object value = parameter.getValue();
|
||||
final JdbcMapping valueMapping = parameter.getValueMapping();
|
||||
|
||||
if ( value instanceof Iterable
|
||||
&& !valueMapping.getJavaTypeDescriptor().isInstance( value ) ) {
|
||||
processIterableFilterParameterValue( valueMapping, ( (Iterable<?>) value ).iterator() );
|
||||
}
|
||||
else {
|
||||
processSingularFilterParameterValue( valueMapping, value );
|
||||
}
|
||||
|
||||
return markerStart + marker.length();
|
||||
}
|
||||
|
||||
private void processSingularFilterParameterValue(JdbcMapping valueMapping, Object value) {
|
||||
visitParameterAsParameter( new FilterJdbcParameter( valueMapping, value ) );
|
||||
}
|
||||
|
||||
private void processIterableFilterParameterValue(JdbcMapping valueMapping, Iterator<?> iterator) {
|
||||
while ( iterator.hasNext() ) {
|
||||
final Object element = iterator.next();
|
||||
processSingularFilterParameterValue( valueMapping, element );
|
||||
if ( iterator.hasNext() ) {
|
||||
appendSql( "," );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,20 +9,24 @@ package org.hibernate.sql.ast.tree.predicate;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.engine.spi.FilterDefinition;
|
||||
import org.hibernate.internal.FilterImpl;
|
||||
import org.hibernate.internal.FilterJdbcParameter;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.JdbcMappingContainer;
|
||||
import org.hibernate.sql.ast.SqlAstWalker;
|
||||
|
||||
/**
|
||||
* Represents a filter applied to an entity/collection.
|
||||
* <p>
|
||||
* Note, we do not attempt to parse the filter
|
||||
* Collection of {@link FilterFragmentPredicate} sub-predicates, each
|
||||
* representing one {@linkplain org.hibernate.Filter enabled filter} restriction.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Nathan Xu
|
||||
*/
|
||||
public class FilterPredicate implements Predicate {
|
||||
private Junction fragments = new Junction();
|
||||
private final List<FilterFragmentPredicate> fragments = new ArrayList<>();
|
||||
|
||||
private List<FilterJdbcParameter> parameters;
|
||||
|
||||
public FilterPredicate() {
|
||||
|
@ -32,8 +36,8 @@ public class FilterPredicate implements Predicate {
|
|||
fragments.add( predicate );
|
||||
}
|
||||
|
||||
public void applyFragment(String sqlFragment) {
|
||||
fragments.add( new FilterFragmentPredicate( sqlFragment ) );
|
||||
public void applyFragment(String processedFragment, FilterImpl filter, List<String> parameterNames) {
|
||||
fragments.add( new FilterFragmentPredicate( processedFragment, filter, parameterNames ) );
|
||||
}
|
||||
|
||||
public void applyParameter(FilterJdbcParameter parameter) {
|
||||
|
@ -43,7 +47,7 @@ public class FilterPredicate implements Predicate {
|
|||
parameters.add( parameter );
|
||||
}
|
||||
|
||||
public Junction getFragments() {
|
||||
public List<FilterFragmentPredicate> getFragments() {
|
||||
return fragments;
|
||||
}
|
||||
|
||||
|
@ -65,17 +69,78 @@ public class FilterPredicate implements Predicate {
|
|||
public JdbcMappingContainer getExpressionType() {
|
||||
return null;
|
||||
}
|
||||
public static class FilterFragmentPredicate implements Predicate {
|
||||
private final String sqlFragment;
|
||||
|
||||
public FilterFragmentPredicate(String sqlFragment) {
|
||||
public static class FilterFragmentParameter {
|
||||
private final String filterName;
|
||||
private final String parameterName;
|
||||
private final JdbcMapping valueMapping;
|
||||
private final Object value;
|
||||
|
||||
public FilterFragmentParameter(String filterName, String parameterName, JdbcMapping valueMapping, Object value) {
|
||||
this.filterName = filterName;
|
||||
this.parameterName = parameterName;
|
||||
this.valueMapping = valueMapping;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getFilterName() {
|
||||
return filterName;
|
||||
}
|
||||
|
||||
public String getParameterName() {
|
||||
return parameterName;
|
||||
}
|
||||
|
||||
public JdbcMapping getValueMapping() {
|
||||
return valueMapping;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FilterFragmentPredicate implements Predicate {
|
||||
private final FilterImpl filter;
|
||||
private final String sqlFragment;
|
||||
private final List<FilterFragmentParameter> parameters;
|
||||
|
||||
public FilterFragmentPredicate(String sqlFragment, FilterImpl filter, List<String> parameterNames) {
|
||||
this.filter = filter;
|
||||
this.sqlFragment = sqlFragment;
|
||||
|
||||
if ( CollectionHelper.isEmpty( parameterNames ) ) {
|
||||
parameters = null;
|
||||
}
|
||||
else {
|
||||
parameters = CollectionHelper.arrayList( parameterNames.size() );
|
||||
for ( int i = 0; i < parameterNames.size(); i++ ) {
|
||||
final String paramName = parameterNames.get( i );
|
||||
final Object paramValue = filter.getParameter( paramName );
|
||||
final FilterDefinition filterDefinition = filter.getFilterDefinition();
|
||||
final JdbcMapping jdbcMapping = filterDefinition.getParameterJdbcMapping( paramName );
|
||||
|
||||
parameters.add( new FilterFragmentParameter( filter.getName(), paramName, jdbcMapping, paramValue ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FilterImpl getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public String getFilterName() {
|
||||
return filter.getName();
|
||||
}
|
||||
|
||||
public String getSqlFragment() {
|
||||
return sqlFragment;
|
||||
}
|
||||
|
||||
public List<FilterFragmentParameter> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(SqlAstWalker sqlTreeWalker) {
|
||||
sqlTreeWalker.visitFilterFragmentPredicate( this );
|
||||
|
|
|
@ -24,6 +24,6 @@ public class AbstractJdbcOperationQueryInsert extends AbstractJdbcOperationQuery
|
|||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames) {
|
||||
super( sql, parameterBinders, affectedTableNames, Collections.emptySet() );
|
||||
super( sql, parameterBinders, affectedTableNames );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,11 +112,6 @@ public class JdbcCallImpl implements JdbcOperationQueryCall {
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnParameterBindings() {
|
||||
return false;
|
||||
|
|
|
@ -24,9 +24,12 @@ public class AbstractJdbcOperationQuery implements JdbcOperationQuery {
|
|||
protected final String sql;
|
||||
protected final List<JdbcParameterBinder> parameterBinders;
|
||||
protected final Set<String> affectedTableNames;
|
||||
protected final Set<FilterJdbcParameter> filterJdbcParameters;
|
||||
protected final Map<JdbcParameter, JdbcParameterBinding> appliedParameters;
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public AbstractJdbcOperationQuery(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
|
@ -35,22 +38,43 @@ public class AbstractJdbcOperationQuery implements JdbcOperationQuery {
|
|||
this(
|
||||
sql,
|
||||
parameterBinders,
|
||||
affectedTableNames,
|
||||
filterJdbcParameters,
|
||||
Collections.emptyMap()
|
||||
affectedTableNames
|
||||
);
|
||||
}
|
||||
|
||||
public AbstractJdbcOperationQuery(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames) {
|
||||
this(
|
||||
sql,
|
||||
parameterBinders,
|
||||
affectedTableNames,
|
||||
Collections.emptyMap()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public AbstractJdbcOperationQuery(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Set<FilterJdbcParameter> filterJdbcParameters,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
this( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
}
|
||||
|
||||
public AbstractJdbcOperationQuery(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
this.sql = sql;
|
||||
this.parameterBinders = parameterBinders;
|
||||
this.affectedTableNames = affectedTableNames;
|
||||
this.filterJdbcParameters = filterJdbcParameters;
|
||||
this.appliedParameters = appliedParameters;
|
||||
}
|
||||
|
||||
|
@ -69,11 +93,6 @@ public class AbstractJdbcOperationQuery implements JdbcOperationQuery {
|
|||
return affectedTableNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return filterJdbcParameters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnParameterBindings() {
|
||||
return !appliedParameters.isEmpty();
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
*/
|
||||
package org.hibernate.sql.exec.spi;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.internal.FilterJdbcParameter;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
||||
/**
|
||||
|
@ -28,8 +28,13 @@ public interface JdbcOperationQuery extends JdbcOperation {
|
|||
* Any parameters to apply for filters
|
||||
*
|
||||
* @see org.hibernate.annotations.Filter
|
||||
*
|
||||
* @deprecated No longer used.
|
||||
*/
|
||||
Set<FilterJdbcParameter> getFilterJdbcParameters();
|
||||
@Deprecated(since = "6.2")
|
||||
default Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that the SQL depends on the parameter bindings e.g. due to the need for inlining
|
||||
|
@ -38,12 +43,4 @@ public interface JdbcOperationQuery extends JdbcOperation {
|
|||
boolean dependsOnParameterBindings();
|
||||
|
||||
boolean isCompatibleWith(JdbcParameterBindings jdbcParameterBindings, QueryOptions queryOptions);
|
||||
|
||||
default void bindFilterJdbcParameters(JdbcParameterBindings jdbcParameterBindings) {
|
||||
if ( CollectionHelper.isNotEmpty( getFilterJdbcParameters() ) ) {
|
||||
for ( FilterJdbcParameter filterJdbcParameter : getFilterJdbcParameters() ) {
|
||||
jdbcParameterBindings.addBinding( filterJdbcParameter.getParameter(), filterJdbcParameter.getBinding() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,24 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
|||
*/
|
||||
public class JdbcOperationQueryDelete extends AbstractJdbcOperationQuery implements JdbcOperationQueryMutation {
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public JdbcOperationQueryDelete(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Set<FilterJdbcParameter> filterJdbcParameters,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
super( sql, parameterBinders, affectedTableNames, filterJdbcParameters, appliedParameters );
|
||||
this( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
}
|
||||
|
||||
public JdbcOperationQueryDelete(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
super( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.sql.exec.spi;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.internal.FilterJdbcParameter;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
|
||||
/**
|
||||
|
@ -47,11 +45,6 @@ public class JdbcOperationQueryMutationNative implements JdbcOperationQueryMutat
|
|||
return affectedTableNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FilterJdbcParameter> getFilterJdbcParameters() {
|
||||
return Collections.EMPTY_SET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dependsOnParameterBindings() {
|
||||
return false;
|
||||
|
|
|
@ -30,18 +30,35 @@ public class JdbcOperationQuerySelect extends AbstractJdbcOperationQuery {
|
|||
private final JdbcParameter limitParameter;
|
||||
private final JdbcLockStrategy jdbcLockStrategy;
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public JdbcOperationQuerySelect(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
JdbcValuesMappingProducer jdbcValuesMappingProducer,
|
||||
Set<String> affectedTableNames,
|
||||
Set<FilterJdbcParameter> filterJdbcParameters) {
|
||||
this(
|
||||
sql,
|
||||
parameterBinders,
|
||||
jdbcValuesMappingProducer,
|
||||
affectedTableNames
|
||||
);
|
||||
}
|
||||
|
||||
public JdbcOperationQuerySelect(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
JdbcValuesMappingProducer jdbcValuesMappingProducer,
|
||||
Set<String> affectedTableNames) {
|
||||
this(
|
||||
sql,
|
||||
parameterBinders,
|
||||
jdbcValuesMappingProducer,
|
||||
affectedTableNames,
|
||||
filterJdbcParameters,
|
||||
null,
|
||||
0,
|
||||
Integer.MAX_VALUE,
|
||||
Collections.emptyMap(),
|
||||
|
@ -51,6 +68,10 @@ public class JdbcOperationQuerySelect extends AbstractJdbcOperationQuery {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public JdbcOperationQuerySelect(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
|
@ -63,7 +84,32 @@ public class JdbcOperationQuerySelect extends AbstractJdbcOperationQuery {
|
|||
JdbcLockStrategy jdbcLockStrategy,
|
||||
JdbcParameter offsetParameter,
|
||||
JdbcParameter limitParameter) {
|
||||
super( sql, parameterBinders, affectedTableNames, filterJdbcParameters, appliedParameters );
|
||||
this(
|
||||
sql,
|
||||
parameterBinders,
|
||||
jdbcValuesMappingProducer,
|
||||
affectedTableNames,
|
||||
rowsToSkip,
|
||||
maxRows,
|
||||
appliedParameters,
|
||||
jdbcLockStrategy,
|
||||
offsetParameter,
|
||||
limitParameter
|
||||
);
|
||||
}
|
||||
|
||||
public JdbcOperationQuerySelect(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
JdbcValuesMappingProducer jdbcValuesMappingProducer,
|
||||
Set<String> affectedTableNames,
|
||||
int rowsToSkip,
|
||||
int maxRows,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters,
|
||||
JdbcLockStrategy jdbcLockStrategy,
|
||||
JdbcParameter offsetParameter,
|
||||
JdbcParameter limitParameter) {
|
||||
super( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
this.jdbcValuesMappingProducer = jdbcValuesMappingProducer;
|
||||
this.rowsToSkip = rowsToSkip;
|
||||
this.maxRows = maxRows;
|
||||
|
|
|
@ -19,13 +19,24 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
|||
public class JdbcOperationQueryUpdate
|
||||
extends AbstractJdbcOperationQuery
|
||||
implements JdbcOperationQueryMutation {
|
||||
|
||||
/**
|
||||
* @deprecated {@code filterJdbcParameters} is no longer used
|
||||
*/
|
||||
@Deprecated
|
||||
public JdbcOperationQueryUpdate(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Set<FilterJdbcParameter> filterJdbcParameters,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
super( sql, parameterBinders, affectedTableNames, filterJdbcParameters, appliedParameters );
|
||||
this( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
}
|
||||
|
||||
public JdbcOperationQueryUpdate(
|
||||
String sql,
|
||||
List<JdbcParameterBinder> parameterBinders,
|
||||
Set<String> affectedTableNames,
|
||||
Map<JdbcParameter, JdbcParameterBinding> appliedParameters) {
|
||||
super( sql, parameterBinders, affectedTableNames, appliedParameters );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
*/
|
||||
package org.hibernate.orm.test.sql.ast;
|
||||
|
||||
import org.hibernate.annotations.Filter;
|
||||
import org.hibernate.annotations.FilterDef;
|
||||
import org.hibernate.annotations.ParamDef;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.dialect.H2Dialect;
|
||||
import org.hibernate.sql.ast.spi.JdbcParameterRenderer;
|
||||
|
@ -21,6 +24,12 @@ import org.hibernate.testing.orm.junit.SessionFactory;
|
|||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
|
@ -33,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
role = JdbcParameterRenderer.class,
|
||||
impl = JdbcParameterRendererTests.JdbcParameterRendererImpl.class
|
||||
) )
|
||||
@DomainModel( annotatedClasses = EntityOfBasics.class )
|
||||
@DomainModel( annotatedClasses = { EntityOfBasics.class, JdbcParameterRendererTests.EntityWithFilters.class } )
|
||||
@SessionFactory( useCollectingStatementInspector = true )
|
||||
@RequiresDialect( H2Dialect.class )
|
||||
public class JdbcParameterRendererTests {
|
||||
|
@ -52,6 +61,19 @@ public class JdbcParameterRendererTests {
|
|||
final String sql = statementInspector.getSqlQueries().get( 0 );
|
||||
assertThat( sql ).contains( "?1" );
|
||||
}
|
||||
@Test
|
||||
public void testFilters(SessionFactoryScope scope) {
|
||||
final SQLStatementInspector statementInspector = scope.getCollectingStatementInspector();
|
||||
statementInspector.clear();
|
||||
|
||||
scope.inTransaction( (session) -> {
|
||||
session.enableFilter( "region" ).setParameter( "region", "NA" );
|
||||
session.createSelectionQuery( "from EntityWithFilters", EntityWithFilters.class ).list();
|
||||
assertThat( statementInspector.getSqlQueries() ).hasSize( 1 );
|
||||
final String sql = statementInspector.getSqlQueries().get( 0 );
|
||||
assertThat( sql ).contains( "?1" );
|
||||
} );
|
||||
}
|
||||
|
||||
public static class JdbcParameterRendererImpl implements JdbcParameterRenderer {
|
||||
@Override
|
||||
|
@ -59,4 +81,51 @@ public class JdbcParameterRendererTests {
|
|||
jdbcType.appendWriteExpression( "?" + position, appender, dialect );
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "EntityWithFilters" )
|
||||
@Table( name = "filtered_entity" )
|
||||
@FilterDef(
|
||||
name = "region",
|
||||
defaultCondition = "region = :region",
|
||||
parameters = @ParamDef(name = "region", type = String.class)
|
||||
)
|
||||
@Filter( name = "region" )
|
||||
public static class EntityWithFilters {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Basic
|
||||
private String name;
|
||||
@Basic
|
||||
private String region;
|
||||
|
||||
protected EntityWithFilters() {
|
||||
// for use by Hibernate
|
||||
}
|
||||
|
||||
public EntityWithFilters(Integer id, String name, String region) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void setRegion(String region) {
|
||||
this.region = region;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue