Browse Source

DATAMONGO-1335 - DBObjectAccessor now writes all nested fields correctly.

Previously, DBObjectAccessor has always reset the in-between values when traversing nested properties. This caused previously written values to be erased if subsequent values are written. We now reuse an already existing BasicDBObject if present.
pull/663/head
Oliver Gierke 10 years ago
parent
commit
284e2f462d
  1. 34
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DBObjectAccessor.java
  2. 28
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DBObjectAccessorUnitTests.java

34
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/DBObjectAccessor.java

@ -75,9 +75,7 @@ class DBObjectAccessor { @@ -75,9 +75,7 @@ class DBObjectAccessor {
String part = parts.next();
if (parts.hasNext()) {
BasicDBObject nestedDbObject = new BasicDBObject();
dbObject.put(part, nestedDbObject);
dbObject = nestedDbObject;
dbObject = getOrCreateNestedDbObject(part, dbObject);
} else {
dbObject.put(part, value);
}
@ -116,8 +114,14 @@ class DBObjectAccessor { @@ -116,8 +114,14 @@ class DBObjectAccessor {
return result;
}
/**
* Returns the given source object as map, i.e. {@link BasicDBObject}s and maps as is or {@literal null} otherwise.
*
* @param source can be {@literal null}.
* @return
*/
@SuppressWarnings("unchecked")
private Map<String, Object> getAsMap(Object source) {
private static Map<String, Object> getAsMap(Object source) {
if (source instanceof BasicDBObject) {
return (BasicDBObject) source;
@ -129,4 +133,26 @@ class DBObjectAccessor { @@ -129,4 +133,26 @@ class DBObjectAccessor {
return null;
}
/**
* Returns the {@link DBObject} which either already exists in the given source under the given key, or creates a new
* nested one, registers it with the source and returns it.
*
* @param key must not be {@literal null} or empty.
* @param source must not be {@literal null}.
* @return
*/
private static DBObject getOrCreateNestedDbObject(String key, DBObject source) {
Object existing = source.get(key);
if (existing instanceof BasicDBObject) {
return (BasicDBObject) existing;
}
DBObject nested = new BasicDBObject();
source.put(key, nested);
return nested;
}
}

28
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/DBObjectAccessorUnitTests.java

@ -79,6 +79,28 @@ public class DBObjectAccessorUnitTests { @@ -79,6 +79,28 @@ public class DBObjectAccessorUnitTests {
new DBObjectAccessor(null);
}
/**
* @see DATAMONGO-1335
*/
@Test
public void writesAllNestingsCorrectly() {
MongoPersistentEntity<?> entity = context.getPersistentEntity(TypeWithTwoNestings.class);
BasicDBObject target = new BasicDBObject();
DBObjectAccessor accessor = new DBObjectAccessor(target);
accessor.put(entity.getPersistentProperty("id"), "id");
accessor.put(entity.getPersistentProperty("b"), "b");
accessor.put(entity.getPersistentProperty("c"), "c");
DBObject nestedA = DBObjectTestUtils.getAsDBObject(target, "a");
assertThat(nestedA, is(notNullValue()));
assertThat(nestedA.get("b"), is((Object) "b"));
assertThat(nestedA.get("c"), is((Object) "c"));
}
static class ProjectingType {
String name;
@ -91,4 +113,10 @@ public class DBObjectAccessorUnitTests { @@ -91,4 +113,10 @@ public class DBObjectAccessorUnitTests {
String c;
}
static class TypeWithTwoNestings {
String id;
@Field("a.b") String b;
@Field("a.c") String c;
}
}

Loading…
Cancel
Save