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.
1.7.x
Oliver Gierke 10 years ago
parent
commit
f151060773
  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