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 6b12da2

Browse files
committedOct 28, 2024
Simplify QueryParameterSetter.
Replace capturing ErrorHandling with Spring's ErrorHandler and try/catch. Simplify QueryParameterSetterFactory.create(…) to no longer require DeclaredQuery.
1 parent 123dcf6 commit 6b12da2

File tree

9 files changed

+158
-116
lines changed

9 files changed

+158
-116
lines changed
 

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

+2-2
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

+4-6
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

+7-5
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);
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

+100-59
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

+23-24
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.springframework.data.jpa.repository.query.JpaParameters.JpaParameter;
2828
import org.springframework.data.jpa.repository.query.ParameterBinding.BindingIdentifier;
2929
import org.springframework.data.jpa.repository.query.ParameterBinding.MethodInvocationArgument;
30-
import org.springframework.data.jpa.repository.query.QueryParameterSetter.NamedOrIndexedQueryParameterSetter;
3130
import org.springframework.data.repository.query.Parameter;
3231
import org.springframework.data.repository.query.Parameters;
3332
import org.springframework.data.spel.EvaluationContextProvider;
@@ -47,20 +46,25 @@
4746
*/
4847
abstract class QueryParameterSetterFactory {
4948

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

5359
/**
5460
* Creates a new {@link QueryParameterSetterFactory} for the given {@link JpaParameters}.
5561
*
5662
* @param parameters must not be {@literal null}.
63+
* @param preferNamedParameters whether to prefer named parameters.
5764
* @return a basic {@link QueryParameterSetterFactory} that can handle named and index parameters.
5865
*/
59-
static QueryParameterSetterFactory basic(JpaParameters parameters) {
60-
61-
Assert.notNull(parameters, "JpaParameters must not be null");
62-
63-
return new BasicQueryParameterSetterFactory(parameters);
66+
static QueryParameterSetterFactory basic(JpaParameters parameters, boolean preferNamedParameters) {
67+
return new BasicQueryParameterSetterFactory(parameters, preferNamedParameters);
6468
}
6569

6670
/**
@@ -70,9 +74,6 @@ static QueryParameterSetterFactory basic(JpaParameters parameters) {
7074
* @return a {@link QueryParameterSetterFactory} for Part-Tree Queries.
7175
*/
7276
static QueryParameterSetterFactory forPartTreeQuery(JpaParameters parameters) {
73-
74-
Assert.notNull(parameters, "JpaParameters must not be null");
75-
7677
return new PartTreeQueryParameterSetterFactory(parameters);
7778
}
7879

@@ -98,10 +99,6 @@ static QueryParameterSetterFactory forSynthetic() {
9899
*/
99100
static QueryParameterSetterFactory parsing(ValueExpressionParser parser,
100101
ValueEvaluationContextProvider evaluationContextProvider) {
101-
102-
Assert.notNull(parser, "ValueExpressionParser must not be null");
103-
Assert.notNull(evaluationContextProvider, "ValueEvaluationContextProvider must not be null");
104-
105102
return new ExpressionBasedQueryParameterSetterFactory(parser, evaluationContextProvider);
106103
}
107104

@@ -120,7 +117,7 @@ private static QueryParameterSetter createSetter(Function<JpaParametersParameter
120117
? parameter.getRequiredTemporalType() //
121118
: null;
122119

123-
return new NamedOrIndexedQueryParameterSetter(valueExtractor.andThen(binding::prepare),
120+
return QueryParameterSetter.create(valueExtractor.andThen(binding::prepare),
124121
ParameterImpl.of(parameter, binding), temporalType);
125122
}
126123

@@ -187,7 +184,7 @@ private static class ExpressionBasedQueryParameterSetterFactory extends QueryPar
187184

188185
@Nullable
189186
@Override
190-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
187+
public QueryParameterSetter create(ParameterBinding binding) {
191188

192189
if (!(binding.getOrigin() instanceof ParameterBinding.Expression e)) {
193190
return null;
@@ -220,7 +217,7 @@ private Object evaluateExpression(ValueExpression expression, JpaParametersParam
220217
private static class SyntheticParameterSetterFactory extends QueryParameterSetterFactory {
221218

222219
@Override
223-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
220+
public QueryParameterSetter create(ParameterBinding binding) {
224221

225222
if (!(binding.getOrigin() instanceof ParameterBinding.Synthetic s)) {
226223
return null;
@@ -241,19 +238,22 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
241238
private static class BasicQueryParameterSetterFactory extends QueryParameterSetterFactory {
242239

243240
private final JpaParameters parameters;
241+
private final boolean preferNamedParameters;
244242

245243
/**
246244
* @param parameters must not be {@literal null}.
245+
* @param preferNamedParameters whether to use named parameters.
247246
*/
248-
BasicQueryParameterSetterFactory(JpaParameters parameters) {
247+
BasicQueryParameterSetterFactory(JpaParameters parameters, boolean preferNamedParameters) {
249248

250249
Assert.notNull(parameters, "JpaParameters must not be null");
251250

252251
this.parameters = parameters;
252+
this.preferNamedParameters = preferNamedParameters;
253253
}
254254

255255
@Override
256-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
256+
public QueryParameterSetter create(ParameterBinding binding) {
257257

258258
Assert.notNull(binding, "Binding must not be null");
259259

@@ -264,7 +264,7 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
264264
BindingIdentifier identifier = mia.identifier();
265265
JpaParameter parameter;
266266

267-
if (declaredQuery.hasNamedParameter()) {
267+
if (preferNamedParameters) {
268268
parameter = findParameterForBinding(parameters, identifier.getName());
269269
} else {
270270
parameter = findParameterForBinding(parameters, identifier.getPosition() - 1);
@@ -292,12 +292,12 @@ private static class PartTreeQueryParameterSetterFactory extends BasicQueryParam
292292
private final JpaParameters parameters;
293293

294294
private PartTreeQueryParameterSetterFactory(JpaParameters parameters) {
295-
super(parameters);
295+
super(parameters, false);
296296
this.parameters = parameters.getBindableParameters();
297297
}
298298

299299
@Override
300-
public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery declaredQuery) {
300+
public QueryParameterSetter create(ParameterBinding binding) {
301301

302302
if (!binding.getOrigin().isMethodArgument()) {
303303
return null;
@@ -320,7 +320,7 @@ public QueryParameterSetter create(ParameterBinding binding, DeclaredQuery decla
320320
return QueryParameterSetter.NOOP;
321321
}
322322

323-
return super.create(binding, declaredQuery);
323+
return super.create(binding);
324324
}
325325

326326
return null;
@@ -367,7 +367,6 @@ public Integer getPosition() {
367367
public Class<T> getParameterType() {
368368
return parameterType;
369369
}
370-
371370
}
372371

373372
}

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

+1-1
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

+11-9
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

+3-2
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

+7-8
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.