Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1bdffd6

Browse files
committedSep 20, 2024
Simplify QueryParameterSetter.
Replace capturing ErrorHandling with Spring's ErrorHandler and try/catch. Simplify QueryParameterSetterFactory.create(…) to no longer require DeclaredQuery.
1 parent 4f24560 commit 1bdffd6

File tree

9 files changed

+158
-117
lines changed

9 files changed

+158
-117
lines changed
 

‎spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/AbstractJpaQuery.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ private Query applyLockMode(Query query, JpaQueryMethod method) {
235235
return lockModeType == null ? query : query.setLockMode(lockModeType);
236236
}
237237

238-
protected ParameterBinder createBinder() {
239-
return ParameterBinderFactory.createBinder(getQueryMethod().getParameters());
238+
ParameterBinder createBinder() {
239+
return ParameterBinderFactory.createBinder(getQueryMethod().getParameters(), false);
240240
}
241241

242242
protected Query createQuery(JpaParametersParameterAccessor parameters) {

‎spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinder.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.data.jpa.repository.query.QueryParameterSetter.ErrorHandling;
2222
import org.springframework.data.jpa.support.PageableUtils;
2323
import org.springframework.util.Assert;
24+
import org.springframework.util.ErrorHandler;
2425

2526
/**
2627
* {@link ParameterBinder} is used to bind method parameters to a {@link Query}. This is usually done whenever an
@@ -33,9 +34,7 @@
3334
* @author Jens Schauder
3435
* @author Yanming Zhou
3536
*/
36-
// TODO: Refactor, do not create a QueryParameterSetter for each parameter but capture strategies and bindings for more
37-
// efficient binding.
38-
public class ParameterBinder {
37+
class ParameterBinder {
3938

4039
static final String PARAMETER_NEEDS_TO_BE_NAMED = "For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters";
4140

@@ -82,18 +81,17 @@ public <T extends Query> T bind(T jpaQuery,
8281
}
8382

8483
public void bind(QueryParameterSetter.BindableQuery query, JpaParametersParameterAccessor accessor,
85-
ErrorHandling errorHandling) {
84+
ErrorHandler errorHandler) {
8685

8786
for (QueryParameterSetter setter : parameterSetters) {
88-
setter.setParameter(query, accessor, errorHandling);
87+
setter.setParameter(query, accessor, errorHandler);
8988
}
9089
}
9190

9291
/**
9392
* Binds the parameters to the given query and applies special parameter types (e.g. pagination).
9493
*
9594
* @param query must not be {@literal null}.
96-
* @param metadata must not be {@literal null}.
9795
* @param accessor must not be {@literal null}.
9896
*/
9997
Query bindAndPrepare(Query query,

‎spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/ParameterBinderFactory.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,15 @@ class ParameterBinderFactory {
3939
* otherwise.
4040
*
4141
* @param parameters method parameters that are available for binding, must not be {@literal null}.
42+
* @param preferNamedParameters
4243
* @return a {@link ParameterBinder} that can assign values for the method parameters to query parameters of a
4344
* {@link jakarta.persistence.Query}
4445
*/
45-
static ParameterBinder createBinder(JpaParameters parameters) {
46+
static ParameterBinder createBinder(JpaParameters parameters, boolean preferNamedParameters) {
4647

4748
Assert.notNull(parameters, "JpaParameters must not be null");
4849

49-
QueryParameterSetterFactory setterFactory = QueryParameterSetterFactory.basic(parameters);
50+
QueryParameterSetterFactory setterFactory = QueryParameterSetterFactory.basic(parameters, preferNamedParameters);
5051
List<ParameterBinding> bindings = getBindings(parameters);
5152

5253
return new ParameterBinder(parameters, createSetters(bindings, setterFactory));
@@ -95,15 +96,16 @@ static ParameterBinder createQueryAwareBinder(JpaParameters parameters, Declared
9596
QueryParameterSetterFactory expressionSetterFactory = QueryParameterSetterFactory.parsing(parser,
9697
evaluationContextProvider, parameters);
9798

98-
QueryParameterSetterFactory basicSetterFactory = QueryParameterSetterFactory.basic(parameters);
99+
QueryParameterSetterFactory basicSetterFactory = QueryParameterSetterFactory.basic(parameters,
100+
query.hasNamedParameter());
99101

100102
return new ParameterBinder(parameters, createSetters(bindings, query, expressionSetterFactory, basicSetterFactory),
101103
!query.usesPaging());
102104
}
103105

104106
static List<ParameterBinding> getBindings(JpaParameters parameters) {
105107

106-
List<ParameterBinding> result = new ArrayList<>();
108+
List<ParameterBinding> result = new ArrayList<>(parameters.getNumberOfParameters());
107109
int bindableParameterIndex = 0;
108110

109111
for (JpaParameter parameter : parameters) {
@@ -141,7 +143,7 @@ private static QueryParameterSetter createQueryParameterSetter(ParameterBinding
141143

142144
for (QueryParameterSetterFactory strategy : strategies) {
143145

144-
QueryParameterSetter setter = strategy.create(binding, declaredQuery);
146+
QueryParameterSetter setter = strategy.create(binding);
145147

146148
if (setter != null) {
147149
return setter;

‎spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetter.java

Lines changed: 100 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import org.springframework.lang.Nullable;
3434
import org.springframework.util.Assert;
35+
import org.springframework.util.ErrorHandler;
3536

3637
/**
3738
* The interface encapsulates the setting of query parameters which might use a significant number of variations of
@@ -43,119 +44,159 @@
4344
*/
4445
interface QueryParameterSetter {
4546

46-
void setParameter(BindableQuery query, JpaParametersParameterAccessor accessor, ErrorHandling errorHandling);
47-
4847
/** Noop implementation */
49-
QueryParameterSetter NOOP = (query, values, errorHandling) -> {};
48+
QueryParameterSetter NOOP = (query, values, errorHandler) -> {};
49+
50+
/**
51+
* Creates a new {@link QueryParameterSetter} for the given value extractor, JPA parameter and potentially the
52+
* temporal type.
53+
*
54+
* @param valueExtractor
55+
* @param parameter
56+
* @param temporalType
57+
* @return
58+
*/
59+
static QueryParameterSetter create(Function<JpaParametersParameterAccessor, Object> valueExtractor,
60+
Parameter<?> parameter, @Nullable TemporalType temporalType) {
61+
62+
return temporalType == null ? new NamedOrIndexedQueryParameterSetter(valueExtractor, parameter)
63+
: new TemporalParameterSetter(valueExtractor, parameter, temporalType);
64+
}
65+
66+
void setParameter(BindableQuery query, JpaParametersParameterAccessor accessor, ErrorHandler errorHandler);
5067

5168
/**
52-
* {@link QueryParameterSetter} for named or indexed parameters that might have a {@link TemporalType} specified.
69+
* {@link QueryParameterSetter} for named or indexed parameters.
5370
*/
5471
class NamedOrIndexedQueryParameterSetter implements QueryParameterSetter {
5572

5673
private final Function<JpaParametersParameterAccessor, Object> valueExtractor;
5774
private final Parameter<?> parameter;
58-
private final @Nullable TemporalType temporalType;
5975

6076
/**
6177
* @param valueExtractor must not be {@literal null}.
6278
* @param parameter must not be {@literal null}.
63-
* @param temporalType may be {@literal null}.
6479
*/
65-
NamedOrIndexedQueryParameterSetter(Function<JpaParametersParameterAccessor, Object> valueExtractor,
66-
Parameter<?> parameter, @Nullable TemporalType temporalType) {
80+
private NamedOrIndexedQueryParameterSetter(Function<JpaParametersParameterAccessor, Object> valueExtractor,
81+
Parameter<?> parameter) {
6782

6883
Assert.notNull(valueExtractor, "ValueExtractor must not be null");
6984

7085
this.valueExtractor = valueExtractor;
7186
this.parameter = parameter;
72-
this.temporalType = temporalType;
7387
}
7488

75-
// TODO: Refactor to use Spring's ErrorHandler instead of using a capturing ErrorHandling approach.
76-
@SuppressWarnings("unchecked")
7789
@Override
78-
public void setParameter(BindableQuery query, JpaParametersParameterAccessor accessor,
79-
ErrorHandling errorHandling) {
90+
public void setParameter(BindableQuery query, JpaParametersParameterAccessor accessor, ErrorHandler errorHandler) {
8091

81-
if (temporalType != null) {
92+
Object value = valueExtractor.apply(accessor);
8293

83-
Object extractedValue = valueExtractor.apply(accessor);
84-
85-
Date value = (Date) accessor.potentiallyUnwrap(extractedValue);
94+
try {
95+
setParameter(query, value, errorHandler);
96+
} catch (RuntimeException e) {
97+
errorHandler.handleError(e);
98+
}
99+
}
86100

87-
// One would think we can simply use parameter to identify the parameter we want to set.
88-
// But that does not work with list valued parameters. At least Hibernate tries to bind them by name.
89-
// TODO: move to using setParameter(Parameter, value) when https://hibernate.atlassian.net/browse/HHH-11870 is
90-
// fixed.
101+
@SuppressWarnings("unchecked")
102+
private void setParameter(BindableQuery query, Object value, ErrorHandler errorHandler) {
91103

92-
if (parameter instanceof ParameterExpression) {
93-
errorHandling.execute(() -> query.setParameter((Parameter<Date>) parameter, value, temporalType));
94-
} else if (query.hasNamedParameters() && parameter.getName() != null) {
95-
errorHandling.execute(() -> query.setParameter(parameter.getName(), value, temporalType));
96-
} else {
104+
if (parameter instanceof ParameterExpression) {
105+
query.setParameter((Parameter<Object>) parameter, value);
106+
} else if (query.hasNamedParameters() && parameter.getName() != null) {
107+
query.setParameter(parameter.getName(), value);
97108

98-
Integer position = parameter.getPosition();
109+
} else {
99110

100-
if (position != null //
101-
&& (query.getParameters().size() >= parameter.getPosition() //
102-
|| query.registerExcessParameters() //
103-
|| errorHandling == LENIENT)) {
111+
Integer position = parameter.getPosition();
104112

105-
errorHandling.execute(() -> query.setParameter(parameter.getPosition(), value, temporalType));
106-
}
113+
if (position != null //
114+
&& (query.getParameters().size() >= position //
115+
|| errorHandler == LENIENT //
116+
|| query.registerExcessParameters())) {
117+
query.setParameter(position, value);
107118
}
119+
}
120+
}
121+
}
108122

109-
} else {
123+
/**
124+
* {@link QueryParameterSetter} for named or indexed parameters that have a {@link TemporalType} specified.
125+
*/
126+
class TemporalParameterSetter implements QueryParameterSetter {
110127

111-
Object value = valueExtractor.apply(accessor);
128+
private final Function<JpaParametersParameterAccessor, Object> valueExtractor;
129+
private final Parameter<?> parameter;
130+
private final TemporalType temporalType;
131+
132+
private TemporalParameterSetter(Function<JpaParametersParameterAccessor, Object> valueExtractor,
133+
Parameter<?> parameter, TemporalType temporalType) {
134+
this.valueExtractor = valueExtractor;
135+
this.parameter = parameter;
136+
this.temporalType = temporalType;
137+
}
138+
139+
@Override
140+
public void setParameter(BindableQuery query, JpaParametersParameterAccessor accessor, ErrorHandler errorHandler) {
141+
142+
Date value = (Date) accessor.potentiallyUnwrap(valueExtractor.apply(accessor));
143+
144+
try {
145+
setParameter(query, value, errorHandler);
146+
} catch (RuntimeException e) {
147+
errorHandler.handleError(e);
148+
}
149+
}
112150

113-
if (parameter instanceof ParameterExpression) {
114-
errorHandling.execute(() -> query.setParameter((Parameter<Object>) parameter, value));
115-
} else if (query.hasNamedParameters() && parameter.getName() != null) {
116-
errorHandling.execute(() -> query.setParameter(parameter.getName(), value));
151+
@SuppressWarnings("unchecked")
152+
private void setParameter(BindableQuery query, Date date, ErrorHandler errorHandler) {
153+
154+
// One would think we can simply use parameter to identify the parameter we want to set.
155+
// But that does not work with list valued parameters. At least Hibernate tries to bind them by name.
156+
// TODO: move to using setParameter(Parameter, value) when https://hibernate.atlassian.net/browse/HHH-11870 is
157+
// fixed.
117158

118-
} else {
159+
if (parameter instanceof ParameterExpression) {
160+
query.setParameter((Parameter<Date>) parameter, date, temporalType);
161+
} else if (query.hasNamedParameters() && parameter.getName() != null) {
162+
query.setParameter(parameter.getName(), date, temporalType);
163+
} else {
119164

120-
Integer position = parameter.getPosition();
165+
Integer position = parameter.getPosition();
121166

122-
if (position != null //
123-
&& (query.getParameters().size() >= position //
124-
|| errorHandling == LENIENT //
125-
|| query.registerExcessParameters())) {
126-
errorHandling.execute(() -> query.setParameter(position, value));
127-
}
167+
if (position != null //
168+
&& (query.getParameters().size() >= parameter.getPosition() //
169+
|| query.registerExcessParameters() //
170+
|| errorHandler == LENIENT)) {
171+
172+
query.setParameter(parameter.getPosition(), date, temporalType);
128173
}
129174
}
130175
}
131176
}
132177

133-
enum ErrorHandling {
178+
enum ErrorHandling implements ErrorHandler {
134179

135180
STRICT {
136181

137182
@Override
138-
public void execute(Runnable block) {
139-
block.run();
183+
public void handleError(Throwable t) {
184+
if (t instanceof RuntimeException rx) {
185+
throw rx;
186+
}
187+
throw new RuntimeException(t);
140188
}
141189
},
142190

143191
LENIENT {
144192

145193
@Override
146-
public void execute(Runnable block) {
147-
148-
try {
149-
block.run();
150-
} catch (RuntimeException rex) {
151-
LOG.info("Silently ignoring", rex);
152-
}
194+
public void handleError(Throwable t) {
195+
LOG.info("Silently ignoring", t);
153196
}
154197
};
155198

156199
private static final Log LOG = LogFactory.getLog(ErrorHandling.class);
157-
158-
abstract void execute(Runnable block);
159200
}
160201

161202
/**

‎spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactory.java

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter;
2424
import org.springframework.data.jpa.repository.query.ParameterBinding.BindingIdentifier;
2525
import org.springframework.data.jpa.repository.query.ParameterBinding.MethodInvocationArgument;
26-
import org.springframework.data.jpa.repository.query.QueryParameterSetter.NamedOrIndexedQueryParameterSetter;
2726
import org.springframework.data.repository.query.Parameter;
2827
import org.springframework.data.repository.query.Parameters;
2928
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
@@ -45,20 +44,25 @@
4544
*/
4645
abstract class QueryParameterSetterFactory {
4746

47+
/**
48+
* Creates a {@link QueryParameterSetter} for the given {@link ParameterBinding}. This factory may return
49+
* {@literal null} if it doesn't support the given {@link ParameterBinding}.
50+
*
51+
* @param binding the parameter binding to create a {@link QueryParameterSetter} for.
52+
* @return
53+
*/
4854
@Nullable
49-
abstract QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery);
55+
abstract QueryParameterSetter create(ParameterBinding binding);
5056

5157
/**
5258
* Creates a new {@link QueryParameterSetterFactory} for the given {@link JpaParameters}.
5359
*
5460
* @param parameters must not be {@literal null}.
61+
* @param preferNamedParameters whether to prefer named parameters.
5562
* @return a basic {@link QueryParameterSetterFactory} that can handle named and index parameters.
5663
*/
57-
static QueryParameterSetterFactory basic(JpaParameters parameters) {
58-
59-
Assert.notNull(parameters, "JpaParameters must not be null");
60-
61-
return new BasicQueryParameterSetterFactory(parameters);
64+
static QueryParameterSetterFactory basic(JpaParameters parameters, boolean preferNamedParameters) {
65+
return new BasicQueryParameterSetterFactory(parameters, preferNamedParameters);
6266
}
6367

6468
/**
@@ -68,9 +72,6 @@ static QueryParameterSetterFactory basic(JpaParameters parameters) {
6872
* @return a {@link QueryParameterSetterFactory} for Part-Tree Queries.
6973
*/
7074
static QueryParameterSetterFactory forPartTreeQuery(JpaParameters parameters) {
71-
72-
Assert.notNull(parameters, "JpaParameters must not be null");
73-
7475
return new PartTreeQueryParameterSetterFactory(parameters);
7576
}
7677

@@ -96,11 +97,6 @@ static QueryParameterSetterFactory forSynthetic() {
9697
*/
9798
static QueryParameterSetterFactory parsing(SpelExpressionParser parser,
9899
QueryMethodEvaluationContextProvider evaluationContextProvider, Parameters<?, ?> parameters) {
99-
100-
Assert.notNull(parser, "SpelExpressionParser must not be null");
101-
Assert.notNull(evaluationContextProvider, "EvaluationContextProvider must not be null");
102-
Assert.notNull(parameters, "Parameters must not be null");
103-
104100
return new ExpressionBasedQueryParameterSetterFactory(parser, evaluationContextProvider, parameters);
105101
}
106102

@@ -119,7 +115,7 @@ private static QueryParameterSetter createSetter(Function<JpaParametersParameter
119115
? parameter.getRequiredTemporalType() //
120116
: null;
121117

122-
return new NamedOrIndexedQueryParameterSetter(valueExtractor.andThen(binding::prepare),
118+
return QueryParameterSetter.create(valueExtractor.andThen(binding::prepare),
123119
ParameterImpl.of(parameter, binding), temporalType);
124120
}
125121

@@ -189,7 +185,7 @@ private static class ExpressionBasedQueryParameterSetterFactory extends QueryPar
189185

190186
@Nullable
191187
@Override
192-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
188+
public QueryParameterSetter create(ParameterBinding binding) {
193189

194190
if (!(binding.getOrigin() instanceof ParameterBinding.Expression e)) {
195191
return null;
@@ -225,7 +221,7 @@ private Object evaluateExpression(Expression expression, JpaParametersParameterA
225221
private static class SyntheticParameterSetterFactory extends QueryParameterSetterFactory {
226222

227223
@Override
228-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
224+
public QueryParameterSetter create(ParameterBinding binding) {
229225

230226
if (!(binding.getOrigin() instanceof ParameterBinding.Synthetic s)) {
231227
return null;
@@ -246,19 +242,22 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
246242
private static class BasicQueryParameterSetterFactory extends QueryParameterSetterFactory {
247243

248244
private final JpaParameters parameters;
245+
private final boolean preferNamedParameters;
249246

250247
/**
251248
* @param parameters must not be {@literal null}.
249+
* @param preferNamedParameters whether to use named parameters.
252250
*/
253-
BasicQueryParameterSetterFactory(JpaParameters parameters) {
251+
BasicQueryParameterSetterFactory(JpaParameters parameters, boolean preferNamedParameters) {
254252

255253
Assert.notNull(parameters, "JpaParameters must not be null");
256254

257255
this.parameters = parameters;
256+
this.preferNamedParameters = preferNamedParameters;
258257
}
259258

260259
@Override
261-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
260+
public QueryParameterSetter create(ParameterBinding binding) {
262261

263262
Assert.notNull(binding, "Binding must not be null");
264263

@@ -269,7 +268,7 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
269268
BindingIdentifier identifier = mia.identifier();
270269
JpaParameter parameter;
271270

272-
if (declaredQuery.hasNamedParameter()) {
271+
if (preferNamedParameters) {
273272
parameter = findParameterForBinding(parameters, identifier.getName());
274273
} else {
275274
parameter = findParameterForBinding(parameters, identifier.getPosition() - 1);
@@ -297,12 +296,12 @@ private static class PartTreeQueryParameterSetterFactory extends BasicQueryParam
297296
private final JpaParameters parameters;
298297

299298
private PartTreeQueryParameterSetterFactory(JpaParameters parameters) {
300-
super(parameters);
299+
super(parameters, false);
301300
this.parameters = parameters.getBindableParameters();
302301
}
303302

304303
@Override
305-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
304+
public QueryParameterSetter create(ParameterBinding binding) {
306305

307306
if (!binding.getOrigin().isMethodArgument()) {
308307
return null;
@@ -325,7 +324,7 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
325324
return QueryParameterSetter.NOOP;
326325
}
327326

328-
return super.create(binding, declaredQuery);
327+
return super.create(binding);
329328
}
330329

331330
return null;
@@ -372,7 +371,6 @@ public Integer getPosition() {
372371
public Class<T> getParameterType() {
373372
return parameterType;
374373
}
375-
376374
}
377375

378376
}

‎spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/JpaParametersParameterAccessorTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ void createsHibernateParametersParameterAccessor() throws Exception {
6969

7070
private void bind(JpaParameters parameters, JpaParametersParameterAccessor accessor) {
7171

72-
ParameterBinderFactory.createBinder(parameters)
72+
ParameterBinderFactory.createBinder(parameters, true)
7373
.bind( //
7474
QueryParameterSetter.BindableQuery.from(query), //
7575
accessor, //

‎spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/NamedOrIndexedQueryParameterSetterUnitTests.java

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static jakarta.persistence.TemporalType.*;
1919
import static java.util.Arrays.*;
2020
import static org.mockito.Mockito.*;
21+
import static org.springframework.data.jpa.repository.query.QueryParameterSetter.*;
2122
import static org.springframework.data.jpa.repository.query.QueryParameterSetter.ErrorHandling.*;
2223

2324
import jakarta.persistence.Parameter;
@@ -34,7 +35,8 @@
3435
import org.assertj.core.api.SoftAssertions;
3536
import org.junit.jupiter.api.BeforeEach;
3637
import org.junit.jupiter.api.Test;
37-
import org.springframework.data.jpa.repository.query.QueryParameterSetter.NamedOrIndexedQueryParameterSetter;
38+
39+
import org.springframework.data.jpa.repository.query.QueryParameterSetter.*;
3840

3941
/**
4042
* Unit tests fir {@link NamedOrIndexedQueryParameterSetter}.
@@ -79,15 +81,15 @@ void strictErrorHandlingThrowsExceptionForAllVariationsOfParameters() {
7981
for (Parameter parameter : parameters) {
8082
for (TemporalType temporalType : temporalTypes) {
8183

82-
NamedOrIndexedQueryParameterSetter setter = new NamedOrIndexedQueryParameterSetter( //
84+
QueryParameterSetter setter = QueryParameterSetter.create( //
8385
firstValueExtractor, //
8486
parameter, //
8587
temporalType //
8688
);
8789

8890
softly
8991
.assertThatThrownBy(
90-
() -> setter.setParameter(QueryParameterSetter.BindableQuery.from(query), methodArguments, STRICT)) //
92+
() -> setter.setParameter(BindableQuery.from(query), methodArguments, STRICT)) //
9193
.describedAs("p-type: %s, p-name: %s, p-position: %s, temporal: %s", //
9294
parameter.getClass(), //
9395
parameter.getName(), //
@@ -108,15 +110,15 @@ void lenientErrorHandlingThrowsNoExceptionForAllVariationsOfParameters() {
108110
for (Parameter<?> parameter : parameters) {
109111
for (TemporalType temporalType : temporalTypes) {
110112

111-
NamedOrIndexedQueryParameterSetter setter = new NamedOrIndexedQueryParameterSetter( //
113+
QueryParameterSetter setter = QueryParameterSetter.create( //
112114
firstValueExtractor, //
113115
parameter, //
114116
temporalType //
115117
);
116118

117119
softly
118120
.assertThatCode(
119-
() -> setter.setParameter(QueryParameterSetter.BindableQuery.from(query), methodArguments, LENIENT)) //
121+
() -> setter.setParameter(BindableQuery.from(query), methodArguments, LENIENT)) //
120122
.describedAs("p-type: %s, p-name: %s, p-position: %s, temporal: %s", //
121123
parameter.getClass(), //
122124
parameter.getName(), //
@@ -141,13 +143,13 @@ void lenientSetsParameterWhenSuccessIsUnsure() {
141143

142144
for (TemporalType temporalType : temporalTypes) {
143145

144-
NamedOrIndexedQueryParameterSetter setter = new NamedOrIndexedQueryParameterSetter( //
146+
QueryParameterSetter setter = QueryParameterSetter.create( //
145147
firstValueExtractor, //
146148
new ParameterImpl(null, 11), // parameter position is beyond number of parametes in query (0)
147149
temporalType //
148150
);
149151

150-
setter.setParameter(QueryParameterSetter.BindableQuery.from(query), methodArguments, LENIENT);
152+
setter.setParameter(BindableQuery.from(query), methodArguments, LENIENT);
151153

152154
if (temporalType == null) {
153155
verify(query).setParameter(eq(11), any(Date.class));
@@ -171,13 +173,13 @@ void parameterNotSetWhenSuccessImpossible() {
171173

172174
for (TemporalType temporalType : temporalTypes) {
173175

174-
NamedOrIndexedQueryParameterSetter setter = new NamedOrIndexedQueryParameterSetter( //
176+
QueryParameterSetter setter = QueryParameterSetter.create( //
175177
firstValueExtractor, //
176178
new ParameterImpl(null, null), // no position (and no name) makes a success of a setParameter impossible
177179
temporalType //
178180
);
179181

180-
setter.setParameter(QueryParameterSetter.BindableQuery.from(query), methodArguments, LENIENT);
182+
setter.setParameter(BindableQuery.from(query), methodArguments, LENIENT);
181183

182184
if (temporalType == null) {
183185
verify(query, never()).setParameter(anyInt(), any(Date.class));

‎spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/ParameterBinderUnitTests.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,12 +274,13 @@ private void bind(Method method, Object[] values) {
274274
}
275275

276276
private void bind(Method method, JpaParameters parameters, Object[] values) {
277-
ParameterBinderFactory.createBinder(parameters).bind(QueryParameterSetter.BindableQuery.from(query),
277+
ParameterBinderFactory.createBinder(parameters, false).bind(QueryParameterSetter.BindableQuery.from(query),
278278
getAccessor(method, values), QueryParameterSetter.ErrorHandling.STRICT);
279279
}
280280

281281
private void bindAndPrepare(Method method, Object[] values) {
282-
ParameterBinderFactory.createBinder(createParameters(method)).bindAndPrepare(query, getAccessor(method, values));
282+
ParameterBinderFactory.createBinder(createParameters(method), false).bindAndPrepare(query,
283+
getAccessor(method, values));
283284
}
284285

285286
private JpaParametersParameterAccessor getAccessor(Method method, Object... values) {

‎spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryParameterSetterFactoryUnitTests.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ void before() {
4747
// we have one bindable parameter
4848
when(parameters.getBindableParameters().iterator()).thenReturn(Stream.of(mock(JpaParameter.class)).iterator());
4949

50-
setterFactory = QueryParameterSetterFactory.basic(parameters);
50+
setterFactory = QueryParameterSetterFactory.basic(parameters, true);
5151
}
5252

5353
@Test // DATAJPA-1058
5454
void noExceptionWhenQueryDoesNotContainNamedParameters() {
55-
setterFactory.create(binding, DeclaredQuery.of("from Employee e", false));
55+
setterFactory.create(binding);
5656
}
5757

5858
@Test // DATAJPA-1058
@@ -61,8 +61,8 @@ void exceptionWhenQueryContainNamedParametersAndMethodParametersAreNotNamed() {
6161
when(binding.getOrigin()).thenReturn(ParameterOrigin.ofParameter("NamedParameter", 1));
6262

6363
assertThatExceptionOfType(IllegalStateException.class) //
64-
.isThrownBy(() -> setterFactory.create(binding,
65-
DeclaredQuery.of("from Employee e where e.name = :NamedParameter", false))) //
64+
.isThrownBy(() -> setterFactory.create(binding
65+
)) //
6666
.withMessageContaining("Java 8") //
6767
.withMessageContaining("@Param") //
6868
.withMessageContaining("-parameters");
@@ -79,23 +79,22 @@ void exceptionWhenCriteriaQueryContainsInsufficientAmountOfParameters() {
7979
when(binding.getOrigin()).thenReturn(ParameterOrigin.ofParameter(null, 1));
8080

8181
assertThatExceptionOfType(IllegalArgumentException.class) //
82-
.isThrownBy(() -> setterFactory.create(binding,
83-
DeclaredQuery.of("from Employee e where e.name = :NamedParameter", false))) //
82+
.isThrownBy(() -> setterFactory.create(binding)) //
8483
.withMessage("At least 1 parameter(s) provided but only 0 parameter(s) present in query");
8584
}
8685

8786
@Test // DATAJPA-1281
8887
void exceptionWhenBasicQueryContainsInsufficientAmountOfParameters() {
8988

9089
// no parameter present in the criteria query
91-
QueryParameterSetterFactory setterFactory = QueryParameterSetterFactory.basic(parameters);
90+
QueryParameterSetterFactory setterFactory = QueryParameterSetterFactory.basic(parameters, false);
9291

9392
// one argument present in the method signature
9493
when(binding.getRequiredPosition()).thenReturn(1);
9594
when(binding.getOrigin()).thenReturn(ParameterOrigin.ofParameter(null, 1));
9695

9796
assertThatExceptionOfType(IllegalArgumentException.class) //
98-
.isThrownBy(() -> setterFactory.create(binding, DeclaredQuery.of("from Employee e where e.name = ?1", false))) //
97+
.isThrownBy(() -> setterFactory.create(binding)) //
9998
.withMessage("At least 1 parameter(s) provided but only 0 parameter(s) present in query");
10099
}
101100
}

0 commit comments

Comments
 (0)
Please sign in to comment.