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;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -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.convert.QueryMapper;
import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity; import org.springframework.data.mongodb.core.mapping.MongoPersistentEntity;
import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty; import org.springframework.data.mongodb.core.mapping.MongoPersistentProperty;
import org.springframework.data.mongodb.util.BsonUtils;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
import com.mongodb.DBObject; import com.mongodb.DBObject;
import com.mongodb.DBRef; import com.mongodb.DBRef;
@ -93,7 +96,7 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
return super.visit(expr, context); return super.visit(expr, context);
} }
return converter.convertToMongoType(expr.getConstant()); return toQuerydslMongoType(expr.getConstant());
} }
/* /*
@ -128,7 +131,8 @@ class SpringDataMongodbSerializer extends MongodbSerializer {
Document mappedIdValue = mapper.getMappedObject((BasicDBObject) superIdValue, Optional.empty()); Document mappedIdValue = mapper.getMappedObject((BasicDBObject) superIdValue, Optional.empty());
return (DBObject) JSON.parse(mappedIdValue.toJson()); 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 {
return property; 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;
import com.mongodb.BasicDBList; import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject; import com.mongodb.BasicDBObject;
import com.mongodb.DBObject; 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.BooleanOperation;
import com.querydsl.core.types.dsl.PathBuilder; import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.core.types.dsl.SimplePath; import com.querydsl.core.types.dsl.SimplePath;
@ -184,6 +186,16 @@ public class SpringDataMongodbSerializerUnitTests {
assertThat(((DBObject) mappedPredicate).get("sex"), is((Object) "f")); 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 { class Address {
String id; String id;
String street; String street;

Loading…
Cancel
Save