Closed
Description
Mark Paluch opened DATAMONGO-2168 and commented
Using className
as type hint field name fails in in the UpdateMapper
and a nested PropertyPath
resolution with
InvalidPersistentPropertyPath: No property 'class' found on class org.springframework.data.mongodb.core.Foo$MyEntity!
Ideally, UpdateMapper
and QueryMapper
ignore type hint fields during mapping as this also prevents PropertyReferenceException
that happens in MetadataBackedField.getPath
(that's why _class
works).
The problem was originally reported through Gitter in the context of migrating from Morphia to Spring Data MongoDB as Morphia uses className
to store type hints.
Full stack trace:
org.springframework.data.mapping.context.InvalidPersistentPropertyPath: No property 'class' found on class org.springframework.data.mongodb.core.Foo$MyEntity! Did you mean: ?
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:215)
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$2(PersistentPropertyPathFactory.java:182)
at java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:324)
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:181)
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:96)
at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:109)
at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:275)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:990)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:873)
at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:850)
at org.springframework.data.mongodb.core.convert.UpdateMapper$MetadataBackedUpdateField.<init>(UpdateMapper.java:289)
at org.springframework.data.mongodb.core.convert.UpdateMapper.createPropertyField(UpdateMapper.java:249)
at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:142)
at org.springframework.data.mongodb.core.convert.UpdateMapper.getMappedObject(UpdateMapper.java:67)
at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:1582)
at org.springframework.data.mongodb.core.MongoTemplate$8.doInCollection(MongoTemplate.java:1563)
at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:536)
at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:1563)
at org.springframework.data.mongodb.core.MongoTemplate.doSaveVersioned(MongoTemplate.java:1388)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1361)
at org.springframework.data.mongodb.core.MongoTemplate.save(MongoTemplate.java:1348)
public class Reproducer {
@Test
public void reproducer() {
MongoMappingContext context = new MongoMappingContext();
MappingMongoConverter converter = new MappingMongoConverter(NoOpDbRefResolver.INSTANCE, context);
converter.setTypeMapper(new DefaultMongoTypeMapper("className"));
MongoTemplate template = new MongoTemplate(new SimpleMongoClientDbFactory("mongodb://localhost/test"), converter);
List<MyEntity> all = template.findAll(MyEntity.class);
MyEntity entity = all.get(0);
entity.setName("foo");
template.save(entity);
}
@Data
static class MyEntity {
ObjectId id;
@Version long version;
String name;
}
}
Affects: 2.0.12 (Kay SR12)
Reference URL: https://gitter.im/spring-projects/spring-data?at=5c1258bb33d9e11991c743bd
Issue Links:
- DATAMONGO-2174 InvalidPersistentPropertyPath with
@Version
Referenced from: pull request #631
Backported to: 2.1.10 (Lovelace SR10)