Skip to content

Commit 4774992

Browse files
christophstroblodrotbohm
authored andcommitted
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.
1 parent 3b70b6a commit 4774992

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ protected void writePropertyInternal(Object obj, DBObject dbo, MongoPersistentPr
503503
Object existingValue = accessor.get(prop);
504504
BasicDBObject propDbObj = existingValue instanceof BasicDBObject ? (BasicDBObject) existingValue
505505
: new BasicDBObject();
506-
addCustomTypeKeyIfNecessary(type, obj, propDbObj);
506+
addCustomTypeKeyIfNecessary(ClassTypeInformation.from(prop.getRawType()), obj, propDbObj);
507507

508508
MongoPersistentEntity<?> entity = isSubtype(prop.getType(), obj.getClass()) ? mappingContext
509509
.getPersistentEntity(obj.getClass()) : mappingContext.getPersistentEntity(type);
@@ -700,7 +700,7 @@ protected String potentiallyUnescapeMapKey(String source) {
700700
/**
701701
* Adds custom type information to the given {@link DBObject} if necessary. That is if the value is not the same as
702702
* the one given. This is usually the case if you store a subtype of the actual declared type of the property.
703-
*
703+
*
704704
* @param type
705705
* @param value must not be {@literal null}.
706706
* @param dbObject must not be {@literal null}.

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,6 +1945,31 @@ public void annotatedIdFieldShouldExtractValueFromUnderscoreIdField() {
19451945
assertThat(withAnnotatedIdField.key, is("A"));
19461946
}
19471947

1948+
/**
1949+
* @see DATAMONGO-1086
1950+
*/
1951+
@Test
1952+
public void shouldIncludeClassIdentifierForGenericAbstractTypesInCollections() {
1953+
1954+
ConcreteRoot root = new ConcreteRoot();
1955+
ConcreteSub sub = new ConcreteSub();
1956+
sub.abstractType = new Concrete();
1957+
sub.abstractType.content = "foo";
1958+
root.listOfGenericSub = Collections.singletonList(sub);
1959+
1960+
DBObject dbo = new BasicDBObject();
1961+
converter.write(root, dbo);
1962+
1963+
BasicDBList genericSubType = DBObjectTestUtils.getAsDBList(dbo, "listOfGenericSub");
1964+
assertThat((String) dbo.get("_class"), is(ConcreteRoot.class.getName()));
1965+
1966+
DBObject item0 = DBObjectTestUtils.getAsDBObject(genericSubType, 0);
1967+
assertThat(item0.get("_class"), nullValue());
1968+
1969+
DBObject abstractType = DBObjectTestUtils.getAsDBObject(item0, "abstractType");
1970+
assertThat((String) abstractType.get("_class"), is(Concrete.class.getName()));
1971+
}
1972+
19481973
static class GenericType<T> {
19491974
T content;
19501975
}
@@ -2232,4 +2257,28 @@ static class ClassWithAnnotatedIdField {
22322257

22332258
@Id String key;
22342259
}
2260+
2261+
static abstract class AbstractGenericRoot<T extends GenericSub<?>> {
2262+
List<T> listOfGenericSub;
2263+
}
2264+
2265+
static class ConcreteRoot extends AbstractGenericRoot<ConcreteSub> {
2266+
2267+
}
2268+
2269+
static abstract class GenericSub<T extends AbstractRoot> {
2270+
T abstractType;
2271+
}
2272+
2273+
static class ConcreteSub extends GenericSub<Concrete> {
2274+
2275+
}
2276+
2277+
static abstract class AbstractRoot {
2278+
2279+
}
2280+
2281+
static class Concrete extends AbstractRoot {
2282+
String content;
2283+
}
22352284
}

0 commit comments

Comments
 (0)