From 3385d96213426806a5a89f327cbbbc47f658ee3a Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Thu, 9 Feb 2017 13:57:39 +0100 Subject: [PATCH] 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. --- .../ExpressionEvaluatingParameterBinder.java | 12 +++++++++- .../query/StringBasedMongoQueryUnitTests.java | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java index 83489e61b..51de1e455 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/ExpressionEvaluatingParameterBinder.java @@ -170,6 +170,12 @@ class ExpressionEvaluatingParameterBinder { } else { + if (isExpression) { + + buffer.deleteCharAt(quotationMarkIndex); + return; + } + if (quotationMark == '\'') { buffer.replace(quotationMarkIndex, quotationMarkIndex + 1, "\""); } @@ -199,7 +205,7 @@ class ExpressionEvaluatingParameterBinder { return (String) value; } - return QuotedString.unquote(JSON.serialize(value)); + return binding.isExpression() ? JSON.serialize(value) : QuotedString.unquote(JSON.serialize(value)); } if (value instanceof byte[]) { @@ -213,6 +219,10 @@ class ExpressionEvaluatingParameterBinder { return base64representation; } + if (binding.isExpression() && value instanceof String) { + return "\"" + JSON.serialize(value) + "\""; + } + return JSON.serialize(value); } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java index 9e9827d96..c45641b44 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/StringBasedMongoQueryUnitTests.java @@ -581,6 +581,26 @@ public class StringBasedMongoQueryUnitTests { is((DBObject) JSON.parse("{ 'lastname' : { '$regex' : '^(calamity|John regalia|regalia)'} }"))); } + @Test // DATAMONGO-1605 + public void findUsingSpelShouldRetainParameterType() throws Exception { + + StringBasedMongoQuery mongoQuery = createQueryForMethod("findByUsingSpel", Object.class); + ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter, 100.01D); + + org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor); + assertThat(query.getQueryObject(), is((DBObject) new BasicDBObject().append("arg0", 100.01D))); + } + + @Test // DATAMONGO-1605 + public void findUsingSpelShouldRetainNullValues() throws Exception { + + StringBasedMongoQuery mongoQuery = createQueryForMethod("findByUsingSpel", Object.class); + ConvertingParameterAccessor accessor = StubParameterAccessor.getAccessor(converter, new Object[]{null}); + + org.springframework.data.mongodb.core.query.Query query = mongoQuery.createQuery(accessor); + assertThat(query.getQueryObject(), is((DBObject) new BasicDBObject().append("arg0", null))); + } + private StringBasedMongoQuery createQueryForMethod(String name, Class... parameters) throws Exception { Method method = SampleRepository.class.getMethod(name, parameters); @@ -669,5 +689,8 @@ public class StringBasedMongoQueryUnitTests { @Query("{ 'lastname' : { '$regex' : '^(?0|John ?1|?1)'} }") // use spel or some regex string this is fucking bad Person findByLastnameRegex(String lastname, String alternative); + + @Query("{ arg0 : ?#{[0]} }") + List findByUsingSpel(Object arg0); } }