HHH-16260 - JdbcParameterRenderer not called with dynamic filters

This commit is contained in:
Steve Ebersole 2023-03-07 21:26:54 -06:00
parent c86d755d75
commit 07a653aa50
19 changed files with 346 additions and 178 deletions

View File

@ -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] );
}
}

View File

@ -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( );
}
}

View File

@ -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;

View File

@ -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() ) {

View File

@ -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(

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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();

View File

@ -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() );
}
}
}
}

View File

@ -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 );
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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 );
}
}

View File

@ -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;
}
}
}