Skip to content

Commit 5d8f10f

Browse files
christophstroblmp911de
authored andcommitted
DATAMONGO-1605 - Retain type of SpEL expression result when used in @query.
Fix issue where any result of a SpEL expression had been treated as quoted String within the resulting MongoDB query.
1 parent 715408d commit 5d8f10f

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ private void postProcessQuotedBinding(StringBuffer buffer, String valueForBindin
170170

171171
} else {
172172

173+
if (isExpression) {
174+
175+
buffer.deleteCharAt(quotationMarkIndex);
176+
return;
177+
}
178+
173179
if (quotationMark == '\'') {
174180
buffer.replace(quotationMarkIndex, quotationMarkIndex + 1, "\"");
175181
}
@@ -199,7 +205,7 @@ private String getParameterValueForBinding(MongoParameterAccessor accessor, Mong
199205
return (String) value;
200206
}
201207

202-
return QuotedString.unquote(JSON.serialize(value));
208+
return binding.isExpression() ? JSON.serialize(value) : QuotedString.unquote(JSON.serialize(value));
203209
}
204210

205211
if (value instanceof byte[]) {
@@ -213,6 +219,10 @@ private String getParameterValueForBinding(MongoParameterAccessor accessor, Mong
213219
return base64representation;
214220
}
215221

222+
if (binding.isExpression() && value instanceof String) {
223+
return "\"" + JSON.serialize(value) + "\"";
224+
}
225+
216226
return JSON.serialize(value);
217227
}
218228

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,26 @@ public void shouldAllowPlaceholderReuseInQuotedValue() throws Exception {
509509
is((DBObject) JSON.parse("{ 'lastname' : { '$regex' : '^(calamity|John regalia|regalia)'} }")));
510510
}
511511

512+
@Test // DATAMONGO-1605
513+
public void findUsingSpelShouldRetainParameterType() throws Exception {
514+
515+
StringBasedMongoQuery mongoQuery = createQueryForMethod("findByUsingSpel", Object.class);
516+
ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter, 100.01D);
517+
518+
org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor);
519+
assertThat(query.getQueryObject(), is((DBObject) new BasicDBObject().append("arg0", 100.01D)));
520+
}
521+
522+
@Test // DATAMONGO-1605
523+
public void findUsingSpelShouldRetainNullValues() throws Exception {
524+
525+
StringBasedMongoQuery mongoQuery = createQueryForMethod("findByUsingSpel", Object.class);
526+
ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter, new Object[]{null});
527+
528+
org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor);
529+
assertThat(query.getQueryObject(), is((DBObject) new BasicDBObject().append("arg0", null)));
530+
}
531+
512532
private StringBasedMongoQuery createQueryForMethod(String name, Class<?>... parameters) throws Exception {
513533

514534
Method method = SampleRepository.class.getMethod(name, parameters);
@@ -600,5 +620,8 @@ private interface SampleRepository extends Repository<Person, Long> {
600620

601621
@Query("{ 'lastname' : { '$regex' : '^(?0|John ?1|?1)'} }") // use spel or some regex string this is fucking bad
602622
Person findByLastnameRegex(String lastname, String alternative);
623+
624+
@Query("{ arg0 : ?#{[0]} }")
625+
List<Person> findByUsingSpel(Object arg0);
603626
}
604627
}

0 commit comments

Comments
 (0)