Browse Source

DATAMONGO-657 - Support DBRef for maps

Added capability to write DBRef instances for map values. Reading had been supported before but writing wasn't.
pull/35/merge
Patryk Wąsik 13 years ago committed by Oliver Gierke
parent
commit
d11c20d548
  1. 40
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java
  2. 48
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

40
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java

@ -71,6 +71,7 @@ import com.mongodb.DBRef;
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Jon Brisbin * @author Jon Brisbin
* @author Patrik Wasik
*/ */
public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware { public class MappingMongoConverter extends AbstractMongoConverter implements ApplicationContextAware {
@ -414,8 +415,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
} }
if (valueType.isMap()) { if (valueType.isMap()) {
BasicDBObject mapDbObj = new BasicDBObject(); DBObject mapDbObj = createMap((Map<Object, Object>) obj, prop);
writeMapInternal((Map<Object, Object>) obj, mapDbObj, type);
dbo.put(name, mapDbObj); dbo.put(name, mapDbObj);
return; return;
} }
@ -495,6 +495,42 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App
return dbList; return dbList;
} }
/**
* Writes the given {@link Map} using the given {@link MongoPersistentProperty} information.
*
* @param map must not {@literal null}.
* @param property must not be {@literal null}.
* @return
*/
protected DBObject createMap(Map<Object, Object> map, MongoPersistentProperty property) {
Assert.notNull(map, "Given map must not be null!");
Assert.notNull(property, "PersistentProperty must not be null!");
if (!property.isDbReference()) {
return writeMapInternal(map, new BasicDBObject(), property.getTypeInformation());
}
BasicDBObject dbObject = new BasicDBObject();
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
if (conversions.isSimpleType(key.getClass())) {
String simpleKey = potentiallyEscapeMapKey(key.toString());
dbObject.put(simpleKey, value != null ? createDBRef(value, property.getDBRef()) : null);
} else {
throw new MappingException("Cannot use a complex object as a key value.");
}
}
return dbObject;
}
/** /**
* Populates the given {@link BasicDBList} with values from the given {@link Collection}. * Populates the given {@link BasicDBList} with values from the given {@link Collection}.
* *

48
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java

@ -72,6 +72,7 @@ import com.mongodb.util.JSON;
* Unit tests for {@link MappingMongoConverter}. * Unit tests for {@link MappingMongoConverter}.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Patrik Wasik
*/ */
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class MappingMongoConverterUnitTests { public class MappingMongoConverterUnitTests {
@ -1321,6 +1322,53 @@ public class MappingMongoConverterUnitTests {
converter.read(ObjectContainer.class, input); converter.read(ObjectContainer.class, input);
} }
/**
* @see DATAMONGO-657
*/
@Test
public void convertDocumentWithMapDBRef() {
MapDBRef mapDBRef = new MapDBRef();
MapDBRefVal val = new MapDBRefVal();
val.id = BigInteger.ONE;
Map<String, MapDBRefVal> mapVal = new HashMap<String, MapDBRefVal>();
mapVal.put("test", val);
mapDBRef.map = mapVal;
BasicDBObject dbObject = new BasicDBObject();
converter.write(mapDBRef, dbObject);
DBObject map = (DBObject) dbObject.get("map");
assertThat(map.get("test"), instanceOf(DBRef.class));
DBObject mapValDBObject = new BasicDBObject();
mapValDBObject.put("_id", BigInteger.ONE);
DBRef dbRef = mock(DBRef.class);
when(dbRef.fetch()).thenReturn(mapValDBObject);
((DBObject) dbObject.get("map")).put("test", dbRef);
MapDBRef read = converter.read(MapDBRef.class, dbObject);
assertThat(read.map.get("test").id, is(BigInteger.ONE));
}
@Document
class MapDBRef {
@org.springframework.data.mongodb.core.mapping.DBRef
Map<String, MapDBRefVal> map;
}
@Document
class MapDBRefVal {
BigInteger id;
}
static class GenericType<T> { static class GenericType<T> {
T content; T content;
} }

Loading…
Cancel
Save