DATAMONGO-705 - Fixed handling of DBRefs in QueryMapper.
QueryMapper now converts values to become DBRefs correctly in getMappedKeyword(…). Added an exclusion path for the value handling in case we have an $exists keyword.
This commit is contained in:
@@ -123,13 +123,13 @@ public class QueryMapper {
|
||||
* @param property
|
||||
* @return
|
||||
*/
|
||||
public DBObject getMappedKeyword(Keyword keyword, Field property) {
|
||||
private DBObject getMappedKeyword(Keyword keyword, Field property) {
|
||||
|
||||
if (property.isAssociation()) {
|
||||
convertAssociation(keyword.value, property.getProperty());
|
||||
}
|
||||
boolean needsAssociationConversion = property.isAssociation() && !keyword.isExists();
|
||||
Object value = needsAssociationConversion ? convertAssociation(keyword.value, property.getProperty())
|
||||
: getMappedValue(keyword.value, property.with(keyword.key));
|
||||
|
||||
return new BasicDBObject(keyword.key, getMappedValue(keyword.value, property.with(keyword.key)));
|
||||
return new BasicDBObject(keyword.key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +196,7 @@ public class QueryMapper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given source assuming it's actually an association to anoter object.
|
||||
* Converts the given source assuming it's actually an association to another object.
|
||||
*
|
||||
* @param source
|
||||
* @param property
|
||||
@@ -256,7 +256,7 @@ public class QueryMapper {
|
||||
String key;
|
||||
Object value;
|
||||
|
||||
Keyword(Object source) {
|
||||
public Keyword(Object source) {
|
||||
|
||||
Assert.isInstanceOf(DBObject.class, source);
|
||||
|
||||
@@ -268,6 +268,15 @@ public class QueryMapper {
|
||||
this.value = value.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current keyword is the {@code $exists} keyword.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isExists() {
|
||||
return "$exists".equalsIgnoreCase(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given value actually represents a keyword. If this returns {@literal true} it's safe to call
|
||||
* the constructor.
|
||||
@@ -275,7 +284,7 @@ public class QueryMapper {
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
static boolean isKeyword(Object value) {
|
||||
public static boolean isKeyword(Object value) {
|
||||
|
||||
if (!(value instanceof DBObject)) {
|
||||
return false;
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.data.mongodb.core.DBObjectUtils;
|
||||
import org.springframework.data.mongodb.core.Person;
|
||||
import org.springframework.data.mongodb.core.mapping.BasicMongoPersistentEntity;
|
||||
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||
import org.springframework.data.mongodb.core.mapping.Field;
|
||||
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
|
||||
@@ -63,8 +64,7 @@ public class QueryMapperUnitTests {
|
||||
MongoMappingContext context;
|
||||
MappingMongoConverter converter;
|
||||
|
||||
@Mock
|
||||
MongoDbFactory factory;
|
||||
@Mock MongoDbFactory factory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@@ -334,7 +334,11 @@ public class QueryMapperUnitTests {
|
||||
DBObject result = mapper.getMappedObject(query.getQueryObject(), context.getPersistentEntity(WithDBRef.class));
|
||||
|
||||
DBObject reference = DBObjectUtils.getAsDBObject(result, "reference");
|
||||
assertThat(reference.containsField("$in"), is(true));
|
||||
|
||||
BasicDBList inClause = getAsDBList(reference, "$in");
|
||||
assertThat(inClause, hasSize(2));
|
||||
assertThat(inClause.get(0), is(instanceOf(com.mongodb.DBRef.class)));
|
||||
assertThat(inClause.get(1), is(instanceOf(com.mongodb.DBRef.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -394,6 +398,22 @@ public class QueryMapperUnitTests {
|
||||
assertThat(mapped.get("_id"), is(instanceOf(ObjectId.class)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-705
|
||||
*/
|
||||
@Test
|
||||
public void convertsDBRefWithExistsQuery() {
|
||||
|
||||
Query query = query(where("reference").exists(false));
|
||||
|
||||
BasicMongoPersistentEntity<?> entity = context.getPersistentEntity(WithDBRef.class);
|
||||
DBObject mappedObject = mapper.getMappedObject(query.getQueryObject(), entity);
|
||||
|
||||
DBObject reference = getAsDBObject(mappedObject, "reference");
|
||||
assertThat(reference.containsField("$exists"), is(true));
|
||||
assertThat(reference.get("$exists"), is((Object) false));
|
||||
}
|
||||
|
||||
class IdWrapper {
|
||||
Object id;
|
||||
}
|
||||
@@ -406,14 +426,12 @@ public class QueryMapperUnitTests {
|
||||
|
||||
class Sample {
|
||||
|
||||
@Id
|
||||
private String foo;
|
||||
@Id private String foo;
|
||||
}
|
||||
|
||||
class BigIntegerId {
|
||||
|
||||
@Id
|
||||
private BigInteger id;
|
||||
@Id private BigInteger id;
|
||||
}
|
||||
|
||||
enum Enum {
|
||||
@@ -427,14 +445,12 @@ public class QueryMapperUnitTests {
|
||||
|
||||
class CustomizedField {
|
||||
|
||||
@Field("foo")
|
||||
CustomizedField field;
|
||||
@Field("foo") CustomizedField field;
|
||||
}
|
||||
|
||||
class WithDBRef {
|
||||
|
||||
@DBRef
|
||||
Reference reference;
|
||||
@DBRef Reference reference;
|
||||
}
|
||||
|
||||
class Reference {
|
||||
@@ -449,7 +465,6 @@ public class QueryMapperUnitTests {
|
||||
|
||||
class WithMapDBRef {
|
||||
|
||||
@DBRef
|
||||
Map<String, Sample> mapWithDBRef;
|
||||
@DBRef Map<String, Sample> mapWithDBRef;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user