From 9f71af42e877c49de0b2db602cacc7350711329b Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Wed, 30 Nov 2011 16:20:25 +0100 Subject: [PATCH] DATAMONGO-329 - Fixed Collection and Map value handling for more open properties. The decision whether a property value was handled as Collection or Map was based on inspecting the property's type which failed for classes using very open property declarations such as: class MyClass { Object something; } We now rather inspect the value type instead of the property. --- .../core/convert/MappingMongoConverter.java | 11 +++--- .../MappingMongoConverterUnitTests.java | 38 ++++++++++++++++++- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java index 6b10c7512..47df0ded0 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/convert/MappingMongoConverter.java @@ -446,16 +446,16 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } String name = prop.getFieldName(); + TypeInformation valueType = ClassTypeInformation.from(obj.getClass()); + TypeInformation type = prop.getTypeInformation(); - if (prop.isCollectionLike()) { + if (valueType.isCollectionLike()) { DBObject collectionInternal = createCollection(asCollection(obj), prop); dbo.put(name, collectionInternal); return; } - TypeInformation type = prop.getTypeInformation(); - - if (prop.isMap()) { + if (valueType.isMap()) { BasicDBObject mapDbObj = new BasicDBObject(); writeMapInternal((Map) obj, mapDbObj, type); dbo.put(name, mapDbObj); @@ -596,7 +596,8 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App writeCollectionInternal(asCollection(val), propertyType.getMapValueType(), new BasicDBList())); } else { DBObject newDbo = new BasicDBObject(); - writeInternal(val, newDbo, propertyType); + TypeInformation valueTypeInfo = propertyType.isMap() ? propertyType.getMapValueType() : ClassTypeInformation.from(Object.class); + writeInternal(val, newDbo, valueTypeInfo); dbo.put(simpleKey, newDbo); } } else { diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java index e9a2e5ff2..8104b034c 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/convert/MappingMongoConverterUnitTests.java @@ -817,7 +817,32 @@ public class MappingMongoConverterUnitTests { assertThat(result, is(dbObject)); } - + /** + * @see DATAMONGO-329 + */ + @Test + public void writesMapAsGenericFieldCorrectly() { + + Map> objectToSave = new HashMap>(); + objectToSave.put("test", new A("testValue")); + + A>> a = new A>>(objectToSave); + DBObject result = new BasicDBObject(); + + converter.write(a, result); + + assertThat((String) result.get(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(A.class.getName())); + assertThat((String) result.get("valueType"), is(HashMap.class.getName())); + + DBObject object = (DBObject) result.get("value"); + assertThat(object, is(notNullValue())); + + DBObject inner = (DBObject) object.get("test"); + assertThat(inner, is(notNullValue())); + assertThat((String) inner.get(DefaultMongoTypeMapper.DEFAULT_TYPE_KEY), is(A.class.getName())); + assertThat((String) inner.get("valueType"), is(String.class.getName())); + assertThat((String) inner.get("value"), is("testValue")); + } class GenericType { T content; @@ -911,6 +936,17 @@ public class MappingMongoConverterUnitTests { @Id BigInteger id; } + + class A { + + String valueType; + T value; + + public A(T value) { + this.valueType = value.getClass().getName(); + this.value = value; + } + } private class LocalDateToDateConverter implements Converter {