DATADOC-96 - Had to tweak the way the QueryMapper works so that it more correctly searches for id properties to convert to _id as well as trying to turn them into ObjectIds if it can. If it can't, it puts the value in as-is.

This commit is contained in:
J. Brisbin
2011-05-12 16:52:03 -05:00
parent 35629f5370
commit 41e49ad3e2
3 changed files with 58 additions and 15 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.data.document.mongodb.mapping;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.Set;
import org.bson.types.CodeWScope;
@@ -41,6 +42,7 @@ public class MongoMappingContext extends AbstractMappingContext<BasicMongoPersis
simpleTypes.add(ObjectId.class);
simpleTypes.add(CodeWScope.class);
simpleTypes.add(Character.class);
simpleTypes.add(BigInteger.class);
}
@Override

View File

@@ -16,10 +16,12 @@
package org.springframework.data.document.mongodb.query;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import org.bson.types.BasicBSONList;
import org.bson.types.ObjectId;
import org.springframework.core.convert.ConversionFailedException;
import org.springframework.data.document.mongodb.convert.MongoConverter;
@@ -39,22 +41,22 @@ public class QueryMapper {
/**
* Creates a new {@link QueryMapper} with the given {@link MongoConverter}.
*
*
* @param converter
*/
public QueryMapper(MongoConverter converter) {
Assert.notNull(converter);
Assert.notNull(converter);
this.converter = converter;
}
/**
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
* {@link PersistentEntity} metadata.
*
* @param query
* @param entity
* @return
*/
/**
* Replaces the property keys used in the given {@link DBObject} with the appropriate keys by using the
* {@link PersistentEntity} metadata.
*
* @param query
* @param entity
* @return
*/
public DBObject getMappedObject(DBObject query, MongoPersistentEntity<?> entity) {
String idKey = null;
if (null != entity && entity.getIdProperty() != null) {
@@ -71,17 +73,25 @@ public class QueryMapper {
Object value = query.get(key);
if (key.equals(idKey)) {
if (value instanceof DBObject) {
if ("$in".equals(key)) {
DBObject valueDbo = (DBObject) value;
if (valueDbo.containsField("$in") || valueDbo.containsField("$nin")) {
String inKey = valueDbo.containsField("$in") ? "$in" : "$nin";
List<Object> ids = new ArrayList<Object>();
for (Object id : (Object[]) ((DBObject) value).get("$in")) {
for (Object id : (Object[]) valueDbo.get(inKey)) {
if (null != converter && !(id instanceof ObjectId)) {
ObjectId oid = converter.convertObjectId(id);
ids.add(oid);
try {
ObjectId oid = converter.convertObjectId(id);
ids.add(oid);
} catch (ConversionFailedException ignored) {
ids.add(id);
}
} else {
ids.add(id);
}
}
newDbo.put("$in", ids.toArray(new ObjectId[ids.size()]));
valueDbo.put(inKey, ids.toArray(new Object[ids.size()]));
} else {
value = getMappedObject((DBObject) value, entity);
}
} else if (null != converter) {
try {
@@ -90,6 +100,15 @@ public class QueryMapper {
}
}
newKey = "_id";
} else if (key.startsWith("$") && key.endsWith("or")) {
// $or/$nor
BasicBSONList conditions = (BasicBSONList) value;
BasicBSONList newConditions = new BasicBSONList();
Iterator iter = conditions.iterator();
while (iter.hasNext()) {
newConditions.add(getMappedObject((DBObject) iter.next(), entity));
}
value = newConditions;
} else {
// TODO: Implement other forms of conversion (like @Alias and whatnot)
}

View File

@@ -122,6 +122,12 @@ public class MappingTests {
assertThat(result2.size(), is(1));
assertNotNull(result2.get(0).getLastName());
assertThat(result2.get(0).getLastName(), is("LastName"));
// Test "in" query
List<PersonCustomIdName> result3 = template.find(new Query(Criteria.where("lastName").in("LastName")), PersonCustomIdName.class);
assertThat(result3.size(), is(1));
assertNotNull(result3.get(0).getLastName());
assertThat(result3.get(0).getLastName(), is("LastName"));
}
@Test
@@ -340,4 +346,20 @@ public class MappingTests {
assertThat(p2.getAddress().getCity(), is("New Town"));
}
@Test
public void testOrQuery() {
PersonPojo p1 = new PersonPojo(1, "first", "");
template.save(p1);
PersonPojo p2 = new PersonPojo(2, "second", "");
template.save(p2);
Query one = query(where("ssn").is(1));
Query two = query(where("ssn").is(2));
List<PersonPojo> results = template.find(new Query().or(one, two), PersonPojo.class);
assertNotNull(results);
assertThat(results.size(), is(2));
assertThat(results.get(1).getSsn(), is(2));
}
}