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.
This commit is contained in:
Christoph Strobl
2014-11-12 10:05:19 +01:00
committed by Oliver Gierke
parent 3b70b6aeee
commit 477499248a
2 changed files with 51 additions and 2 deletions

View File

@@ -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}.

View File

@@ -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> {
T content;
}
@@ -2232,4 +2257,28 @@ public class MappingMongoConverterUnitTests {
@Id String key;
}
static abstract class AbstractGenericRoot<T extends GenericSub<?>> {
List<T> listOfGenericSub;
}
static class ConcreteRoot extends AbstractGenericRoot<ConcreteSub> {
}
static abstract class GenericSub<T extends AbstractRoot> {
T abstractType;
}
static class ConcreteSub extends GenericSub<Concrete> {
}
static abstract class AbstractRoot {
}
static class Concrete extends AbstractRoot {
String content;
}
}