From 9ed5e6886c172b3bc14c89de8bcd64956c0db9f6 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Tue, 26 Jul 2011 23:35:05 +0200 Subject: [PATCH] DATADOC-224 - Inspect value entity metadata in case it's a subtype of the declared property. --- .../core/convert/MappingMongoConverter.java | 16 ++++++++-- .../MappingMongoConverterUnitTests.java | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 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 bd2f9c340..3e39e8af2 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 @@ -440,9 +440,11 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App return; } + TypeInformation type = prop.getTypeInformation(); + if (prop.isMap()) { BasicDBObject mapDbObj = new BasicDBObject(); - writeMapInternal((Map) obj, mapDbObj, prop.getTypeInformation()); + writeMapInternal((Map) obj, mapDbObj, type); dbo.put(name, mapDbObj); return; } @@ -464,10 +466,18 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App } BasicDBObject propDbObj = new BasicDBObject(); - addCustomTypeKeyIfNecessary(prop.getTypeInformation(), obj, propDbObj); - writeInternal(obj, propDbObj, mappingContext.getPersistentEntity(prop.getTypeInformation())); + addCustomTypeKeyIfNecessary(type, obj, propDbObj); + + MongoPersistentEntity entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext + .getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type); + + writeInternal(obj, propDbObj, entity); dbo.put(name, propDbObj); } + + private boolean isSubtype(Class left, Class right) { + return left.isAssignableFrom(right) && !left.equals(right); + } /** * Returns given object as {@link Collection}. Will return the {@link Collection} as is if the source is a 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 d6fa81839..154d0c347 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 @@ -465,6 +465,35 @@ public class MappingMongoConverterUnitTests { assertThat(converter.maybeConvertObject(null), is(nullValue())); } + @Test + public void writesGenericTypeCorrectly() { + + GenericType
type = new GenericType
(); + type.content = new Address(); + type.content.city = "London"; + + BasicDBObject result = new BasicDBObject(); + converter.write(type, result); + + DBObject content = (DBObject) result.get("content"); + assertThat(content.get("_class"), is(notNullValue())); + assertThat(content.get("city"), is(notNullValue())); + } + + @Test + public void readsGenericTypeCorrectly() { + + DBObject address = new BasicDBObject("_class", Address.class.getName()); + address.put("city", "London"); + + GenericType result = converter.read(GenericType.class, new BasicDBObject("content", address)); + assertThat(result.content, is(instanceOf(Address.class))); + + } + + class GenericType { + T content; + } class ClassWithEnumProperty {