From 477499248ac23e33bfddf675c6832d2bd96c1abe Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 12 Nov 2014 10:05:19 +0100 Subject: [PATCH] DATAMONGO-1086 - Mapping fails for collection with two embbeded types that extend a generic abstract. We now use the type information of the raw property type to check if we need to include _class. --- .../core/convert/MappingMongoConverter.java | 4 +- .../MappingMongoConverterUnitTests.java | 49 +++++++++++++++++++ 2 files changed, 51 insertions(+), 2 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 afe46fbe5..72c778049 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 @@ -503,7 +503,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App Object existingValue = accessor.get(prop); BasicDBObject propDbObj = existingValue instanceof BasicDBObject ? (BasicDBObject) existingValue : new BasicDBObject(); - addCustomTypeKeyIfNecessary(type, obj, propDbObj); + addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj); MongoPersistentEntity entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext .getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type); @@ -700,7 +700,7 @@ public class MappingMongoConverter extends AbstractMongoConverter implements App /** * Adds custom type information to the given {@link DBObject} if necessary. That is if the value is not the same as * the one given. This is usually the case if you store a subtype of the actual declared type of the property. - * + * * @param type * @param value must not be {@literal null}. * @param dbObject must not be {@literal null}. 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 9ef9b5f92..2765e0f87 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 @@ -1945,6 +1945,31 @@ public class MappingMongoConverterUnitTests { assertThat(withAnnotatedIdField.key, is("A")); } + /** + * @see DATAMONGO-1086 + */ + @Test + public void shouldIncludeClassIdentifierForGenericAbstractTypesInCollections() { + + ConcreteRoot root = new ConcreteRoot(); + ConcreteSub sub = new ConcreteSub(); + sub.abstractType = new Concrete(); + sub.abstractType.content = "foo"; + root.listOfGenericSub = Collections.singletonList(sub); + + DBObject dbo = new BasicDBObject(); + converter.write(root, dbo); + + BasicDBList genericSubType = DBObjectTestUtils.getAsDBList(dbo, "listOfGenericSub"); + assertThat((String) dbo.get("_class"), is(ConcreteRoot.class.getName())); + + DBObject item0 = DBObjectTestUtils.getAsDBObject(genericSubType, 0); + assertThat(item0.get("_class"), nullValue()); + + DBObject abstractType = DBObjectTestUtils.getAsDBObject(item0, "abstractType"); + assertThat((String) abstractType.get("_class"), is(Concrete.class.getName())); + } + static class GenericType { T content; } @@ -2232,4 +2257,28 @@ public class MappingMongoConverterUnitTests { @Id String key; } + + static abstract class AbstractGenericRoot> { + List listOfGenericSub; + } + + static class ConcreteRoot extends AbstractGenericRoot { + + } + + static abstract class GenericSub { + T abstractType; + } + + static class ConcreteSub extends GenericSub { + + } + + static abstract class AbstractRoot { + + } + + static class Concrete extends AbstractRoot { + String content; + } }