Browse Source

DATAMONGO-1943 - Fix ClassCastException caused by SpringDataMongodbSerializer.

We now convert List-typed predicates to List to BasicDBList to meet MongodbSerializer's expectations for top-level lists used for the $and operator.

Original pull request: #556.
pull/557/merge
Christoph Strobl 8 years ago committed by Mark Paluch
parent
commit
247f30143b
  1. 29
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java
  2. 12
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java

29
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializer.java

@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support; @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.repository.support;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
@ -27,10 +28,12 @@ import org.springframework.data.mongodb.core.convert.MongoConverter; @@ -27,10 +28,12 @@ import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.QueryMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBRef;
@ -93,7 +96,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer { @@ -93,7 +96,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
return super.visit(expr, context);
}
return converter.convertToMongoType(expr.getConstant());
return toQuerydslMongoType(expr.getConstant());
}
/*
@ -128,7 +131,8 @@ class SpringDataMongodbSerializer extends MongodbSerializer { @@ -128,7 +131,8 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
Document mappedIdValue = mapper.getMappedObject((BasicDBObject) superIdValue, Optional.empty());
return (DBObject) JSON.parse(mappedIdValue.toJson());
}
return super.asDBObject(key, value instanceof Pattern ? value : converter.convertToMongoType(value));
return super.asDBObject(key, value instanceof Pattern ? value : toQuerydslMongoType(value));
}
/*
@ -231,4 +235,25 @@ class SpringDataMongodbSerializer extends MongodbSerializer { @@ -231,4 +235,25 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
return property;
}
Object toQuerydslMongoType(Object source) {
Object target = converter.convertToMongoType(source);
if (target instanceof List) {
BasicDBList newList = new BasicDBList();
for (Object item : (List) target) {
if (item instanceof Document) {
newList.add(new BasicDBObject(BsonUtils.asMap((Document) item)));
} else {
newList.add(item);
}
}
return newList;
}
return target;
}
}

12
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/support/SpringDataMongodbSerializerUnitTests.java

@ -45,6 +45,8 @@ import org.springframework.data.mongodb.repository.QPerson; @@ -45,6 +45,8 @@ import org.springframework.data.mongodb.repository.QPerson;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.BooleanOperation;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.SimplePath;
@ -184,6 +186,16 @@ public class SpringDataMongodbSerializerUnitTests { @@ -184,6 +186,16 @@ public class SpringDataMongodbSerializerUnitTests {
assertThat(((DBObject) mappedPredicate).get("sex"), is((Object) "f"));
}
@Test // DATAMONGO-1943
public void shouldRemarshallListsAndDocuments() {
BooleanExpression criteria = QPerson.person.firstname.isNotEmpty()
.and(QPerson.person.firstname.containsIgnoreCase("foo")).not();
assertThat(this.serializer.handle(criteria), is(equalTo(JSON.parse("{ \"$or\" : [ { \"firstname\" : { \"$ne\" : { "
+ "\"$ne\" : \"\"}}} , { \"firstname\" : { \"$not\" : { \"$regex\" : \".*\\\\Qfoo\\\\E.*\" , \"$options\" : \"i\"}}}]}"))));
}
class Address {
String id;
String street;

Loading…
Cancel
Save