DATAMONGO-863 - UpdateMapper doesn't convert raw DBObjects anymore.
UpdateMapper now only performs simple conversion if it encounters a DBObject, instead of deep inspection on keywords used. This allows to use custom clauses nested in Update for operations not directly supported. Original Pull Request: #138.
This commit is contained in:
committed by
Oliver Gierke
parent
c66b9a538c
commit
84040518cf
@@ -138,7 +138,7 @@ public class QueryMapper {
|
||||
value = getMappedValue(field, rawValue);
|
||||
}
|
||||
|
||||
return Collections.singletonMap(key, value).entrySet().iterator().next();
|
||||
return createMapEntry(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +168,7 @@ public class QueryMapper {
|
||||
BasicDBList newConditions = new BasicDBList();
|
||||
|
||||
for (Object condition : conditions) {
|
||||
newConditions.add(condition instanceof DBObject ? getMappedObject((DBObject) condition, entity)
|
||||
newConditions.add(isDBObject(condition) ? getMappedObject((DBObject) condition, entity)
|
||||
: convertSimpleOrDBObject(condition, entity));
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ public class QueryMapper {
|
||||
|
||||
if (documentField.isIdField()) {
|
||||
|
||||
if (value instanceof DBObject) {
|
||||
if (isDBObject(value)) {
|
||||
DBObject valueDbo = (DBObject) value;
|
||||
DBObject resultDbo = new BasicDBObject(valueDbo.toMap());
|
||||
|
||||
@@ -267,13 +267,13 @@ public class QueryMapper {
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
private Object convertSimpleOrDBObject(Object source, MongoPersistentEntity<?> entity) {
|
||||
protected Object convertSimpleOrDBObject(Object source, MongoPersistentEntity<?> entity) {
|
||||
|
||||
if (source instanceof BasicDBList) {
|
||||
return delegateConvertToMongoType(source, entity);
|
||||
}
|
||||
|
||||
if (source instanceof DBObject) {
|
||||
if (isDBObject(source)) {
|
||||
return getMappedObject((DBObject) source, entity);
|
||||
}
|
||||
|
||||
@@ -329,6 +329,40 @@ public class QueryMapper {
|
||||
return createDbRefFor(source, property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given value is a {@link DBObject}.
|
||||
*
|
||||
* @param value can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected final boolean isDBObject(Object value) {
|
||||
return value instanceof DBObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Entry} for the given {@link Field} with the given value.
|
||||
*
|
||||
* @param field must not be {@literal null}.
|
||||
* @param value can be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected final Entry<String, Object> createMapEntry(Field field, Object value) {
|
||||
return createMapEntry(field.getMappedKey(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Entry} with the given key and value.
|
||||
*
|
||||
* @param key must not be {@literal null} or empty.
|
||||
* @param value can be {@literal null}
|
||||
* @return
|
||||
*/
|
||||
private Entry<String, Object> createMapEntry(String key, Object value) {
|
||||
|
||||
Assert.hasText(key, "Key must not be null or empty!");
|
||||
return Collections.singletonMap(key, value).entrySet().iterator().next();
|
||||
}
|
||||
|
||||
private DBRef createDbRefFor(Object source, MongoPersistentProperty property) {
|
||||
|
||||
if (source instanceof DBRef) {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.mongodb.core.convert;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
@@ -76,6 +75,10 @@ public class UpdateMapper extends QueryMapper {
|
||||
@Override
|
||||
protected Entry<String, Object> getMappedObjectForField(Field field, Object rawValue) {
|
||||
|
||||
if (isDBObject(rawValue)) {
|
||||
return createMapEntry(field, convertSimpleOrDBObject(rawValue, field.getPropertyEntity()));
|
||||
}
|
||||
|
||||
if (!isUpdateModifier(rawValue)) {
|
||||
return super.getMappedObjectForField(field, getMappedValue(field, rawValue));
|
||||
}
|
||||
@@ -100,7 +103,7 @@ public class UpdateMapper extends QueryMapper {
|
||||
throw new IllegalArgumentException(String.format("Unable to map value of type '%s'!", rawValue.getClass()));
|
||||
}
|
||||
|
||||
return Collections.singletonMap(field.getMappedKey(), value).entrySet().iterator().next();
|
||||
return createMapEntry(field, value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.collection.IsIterableContainingInOrder;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -390,6 +391,27 @@ public class UpdateMapperUnitTests {
|
||||
assertThat(setClause.containsField("listOfInterface.$.value"), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATAMONGO-863
|
||||
*/
|
||||
@Test
|
||||
public void doesNotConvertRawDbObjects() {
|
||||
|
||||
Update update = new Update();
|
||||
update.pull("options",
|
||||
new BasicDBObject("_id", new BasicDBObject("$in", converter.convertToMongoType(Arrays.asList(1L, 2L)))));
|
||||
|
||||
DBObject mappedObject = mapper.getMappedObject(update.getUpdateObject(),
|
||||
context.getPersistentEntity(ParentClass.class));
|
||||
|
||||
DBObject setClause = getAsDBObject(mappedObject, "$pull");
|
||||
DBObject options = getAsDBObject(setClause, "options");
|
||||
DBObject idClause = getAsDBObject(options, "_id");
|
||||
BasicDBList inClause = getAsDBList(idClause, "$in");
|
||||
|
||||
assertThat(inClause, IsIterableContainingInOrder.<Object> contains(1L, 2L));
|
||||
}
|
||||
|
||||
static interface Model {}
|
||||
|
||||
static class ModelImpl implements Model {
|
||||
|
||||
Reference in New Issue
Block a user