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.
This commit is contained in:
@@ -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 {
|
||||
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 {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
String c;
|
||||
}
|
||||
|
||||
static class TypeWithTwoNestings {
|
||||
|
||||
String id;
|
||||
@Field("a.b") String b;
|
||||
@Field("a.c") String c;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user