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:
Oliver Gierke
2013-06-21 18:57:24 +02:00
parent 187c80dfcc
commit fd28ab4d33
2 changed files with 45 additions and 21 deletions

View File

@@ -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;

View File

@@ -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;
}
}