Skip to content

[3.2.1] Indexing Class with Custom Converter -> Couldn't find PersistentEntity for property private [...] #3659

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
IsNull opened this issue May 26, 2021 · 9 comments
Assignees
Labels
type: regression A regression from a previous release

Comments

@IsNull
Copy link

IsNull commented May 26, 2021

We updated from spring boot 2.4.2 to 2.5.0, and now Index creation is broken. This means the same code that worked before wont under 2.5.0. (spring-data-mongodb 3.1.3 to 3.2.1 )


I have created a sample Project which shows the problem: https://gitlab.com/elderbyte/public/examples/spring-mongo-index-issue


Creating an mongo index fails, when the dot path notation is used and the referenced class is in a separate library has a custom mongo converter:

@Configuration
@EnableMongoRepositories()
public class DefaultMongoConfiguration {


    @Bean
    public MongoCustomConversions customConversions(){
        var converters = new ArrayList<Converter<?,?>>();
        converters.add(new MyAddressToDocumentConverter()); // Comment this out, and it works
        return new MongoCustomConversions(converters);
    }

    @WritingConverter
    public static class MyAddressToDocumentConverter implements Converter<MyAddress, Document> {
        @Override
        public Document convert(MyAddress address) {
            var doc = new Document();
            doc.put("street", address.getStreet());
            return doc;
        }
    }
}

The entity for which this index is being defined looks like this (simplified):

@Document
public class Customer {

    @Id
    private ObjectId id;

    private String name;

    private MyAddress address;

}
public class MyAddress {

    private String street;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

Creating an Index via ensure index yields an unexpected exception:

        indexOps.ensureIndex(
                TextIndexDefinition
                        .builder()
                        .named("TextIndex")
                        .onField("name")
                        .onField("address.street")
                        .build()
        );

Stacktrace

org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for property private com.elderbyte.starter.demo.domain.customers.MyAddress com.elderbyte.starter.demo.domain.customers.Customer.address!
	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:152) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPair(PersistentPropertyPathFactory.java:225) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:199) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$1(PersistentPropertyPathFactory.java:172) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:171) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:86) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:99) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:285) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:1183) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1045) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1022) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.createPropertyField(QueryMapper.java:329) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedSort(QueryMapper.java:197) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.lambda$ensureIndex$0(DefaultIndexOperations.java:130) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:539) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.execute(DefaultIndexOperations.java:211) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.ensureIndex(DefaultIndexOperations.java:121) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at com.elderbyte.starter.demo.domain.customers.CustomerIndexConfiguration.initIndicesAfterStartup(CustomerIndexConfiguration.java:54) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.lambda$running$6(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:352) ~[spring-boot-2.5.0.jar:2.5.0]
	at com.elderbyte.starter.demo.MongodbDemoServer.main(MongodbDemoServer.java:21) ~[main/:na]

2021-05-27 10:59:59.330  INFO 9895 --- [           main] o.s.b.a.ApplicationAvailabilityBean      : Application availability state ReadinessState changed to REFUSING_TRAFFIC
2021-05-27 10:59:59.358  INFO 9895 --- [           main] org.mongodb.driver.connection            : Closed connection [connectionId{localValue:3, serverValue:840}] to localhost:27017 because the pool has been closed.

Process finished with exit code 1

Conclusions:

  • We observed the problem first with Spring Boot 2.5.0 which uses the version 3.2.1 of spring-data-mongodb
    • Therefore it looks like a regression from Spring Boot 2.4.2 where the same code works (3.1.3 of spring-data-mongodb)
    • Edit: Spring Boot 2.4.6 also works (3.1.9 spring-data-mongodb)
  • The class com.elderbyte.commons.i18n.I18nText is in another library which is a gradle (maven) dependency.
  • Repository Base package has been set to com.elderbyte so it should include both classes
  • If I copy the class from that library into the local project, it works.
  • It seems to be caused by the custom converter.
  • If the custom converter is not registered, it works.

Any idea what could have caused this and how to fix it?

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 26, 2021
@christophstrobl
Copy link
Member

Can you please add the structure of all involved classes (I18nText, MaterialPackaging) and the actual call to index ops.
A Minimal, Reproducible Example would help us triage the issue.

@christophstrobl christophstrobl added status: waiting-for-feedback We need additional information before we can continue and removed status: waiting-for-triage An issue we've not yet triaged labels May 26, 2021
@IsNull
Copy link
Author

IsNull commented May 26, 2021

@christophstrobl Thanks for your feedback. While trying to distill a minimal example, I figured out that the issue arises when the following mongo converter is enabled:

    @WritingConverter
    public static class IntervalToDocumentConverter implements Converter<Interval, Document> {
        @Override
        public Document convert(Interval interval) {
            var doc = new Document();
            doc.put("start", Date.from(interval.getStart()));
            doc.put("end", Date.from(interval.getEnd()));
            return doc;
        }
    }

The converter gets registered via MongoCustomConversions.

The Entity:

@Document
public class Customer {
    @Id
    private ObjectId id;

    private String name;
    
    private Interval validInterval;
}

Index creation

public void initIndicesAfterStartup() {

        var indexOps = mongoOperations.indexOps(Customer.class);

        try {
            indexOps.dropIndex("TextIndex");
        }catch (Exception e){}

        indexOps.ensureIndex(
                TextIndexDefinition
                        .builder()
                        .named("TextIndex")
                        .onField("name")
                        .onField("validInterval.start")
                        .build()
        );
    }

With the converter registered, it leads to the following error:


org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for property private com.elderbyte.commons.time.Interval com.elderbyte.starter.demo.domain.customers.Customer.validInterval!
	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:152) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPair(PersistentPropertyPathFactory.java:225) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:199) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$1(PersistentPropertyPathFactory.java:172) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory$$Lambda$1085/0x000000002043ef70.apply(Unknown Source) ~[na:na]
	at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:171) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:86) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:99) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:285) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:1183) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1045) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1022) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.createPropertyField(QueryMapper.java:329) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedSort(QueryMapper.java:197) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.lambda$ensureIndex$0(DefaultIndexOperations.java:130) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations$$Lambda$1081/0x00000000204395d8.doInCollection(Unknown Source) ~[na:na]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:539) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.execute(DefaultIndexOperations.java:211) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.ensureIndex(DefaultIndexOperations.java:121) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at com.elderbyte.starter.demo.domain.customers.CustomerIndexConfiguration.initIndicesAfterStartup(CustomerIndexConfiguration.java:54) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:567) ~[na:na]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.lambda$running$6(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners$$Lambda$1071/0x0000000020016978.accept(Unknown Source) ~[na:na]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:352) ~[spring-boot-2.5.0.jar:2.5.0]
	at com.elderbyte.starter.demo.MongodbDemoServer.main(MongodbDemoServer.java:21) ~[main/:na]

If I disable the converter it works.
It affects all classes I've tested which have a custom converter registered.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels May 26, 2021
@IsNull
Copy link
Author

IsNull commented May 26, 2021

Here is an minimal example project. Simply start the App Server and you will see the exception.

https://gitlab.com/elderbyte/public/examples/spring-mongo-index-issue

@IsNull IsNull changed the title [3.2.1] Indexing Class from library -> Couldn't find PersistentEntity for property private [...] [3.2.1] Indexing Class with Custom Converter -> Couldn't find PersistentEntity for property private [...] May 27, 2021
@IsNull
Copy link
Author

IsNull commented May 27, 2021

@christophstrobl I have now created an reproducible example project & also updated the issue description to reflect the latest discoveries.

@christophstrobl
Copy link
Member

thanks @IsNull - we'll have a look. Might take some time though.

@christophstrobl christophstrobl self-assigned this May 27, 2021
@IsNull
Copy link
Author

IsNull commented May 28, 2021

@christophstrobl Further investigation shows that the problem is not only with custom converters defined by users, but even with standard converters provided by spring.

For example, indexing the spring org.springframework.data.geo.Box which happens to define a MongoConverter in org.springframework.data.mongodb.core.convert.GeoConverters

@Document
public class Customer {

    @Id
    private ObjectId id;

    private String name;
    
    private org.springframework.data.geo.Box box;

}
        indexOps.ensureIndex(
                TextIndexDefinition
                        .builder()
                        .named("TextIndex")
                        .onField("name")
                        .onField("box.first.x")
                        .build()
        );

I consider this a major bug / regression which should be fixed with high priority.

Same Stacktrace:

org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for property private org.springframework.data.geo.Box com.elderbyte.starter.demo.domain.customers.Customer.box!
	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:152) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPair(PersistentPropertyPathFactory.java:225) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:199) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$1(PersistentPropertyPathFactory.java:172) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330) ~[na:na]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:171) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:86) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:99) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:285) ~[spring-data-commons-2.5.1.jar:2.5.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:1183) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1045) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1022) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.createPropertyField(QueryMapper.java:329) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedSort(QueryMapper.java:197) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.lambda$ensureIndex$0(DefaultIndexOperations.java:130) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:553) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:539) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.execute(DefaultIndexOperations.java:211) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at org.springframework.data.mongodb.core.DefaultIndexOperations.ensureIndex(DefaultIndexOperations.java:121) ~[spring-data-mongodb-3.2.1.jar:3.2.1]
	at com.elderbyte.starter.demo.domain.customers.CustomerIndexConfiguration.initIndicesAfterStartup(CustomerIndexConfiguration.java:54) ~[main/:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.doInvoke(ApplicationListenerMethodAdapter.java:344) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.processEvent(ApplicationListenerMethodAdapter.java:229) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.ApplicationListenerMethodAdapter.onApplicationEvent(ApplicationListenerMethodAdapter.java:166) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378) ~[spring-context-5.3.7.jar:5.3.7]
	at org.springframework.boot.context.event.EventPublishingRunListener.running(EventPublishingRunListener.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.lambda$running$6(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:111) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplicationRunListeners.running(SpringApplicationRunListeners.java:79) ~[spring-boot-2.5.0.jar:2.5.0]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:352) ~[spring-boot-2.5.0.jar:2.5.0]
	at com.elderbyte.starter.demo.MongodbDemoServer.main(MongodbDemoServer.java:21) ~[main/:na]

@christophstrobl christophstrobl added the type: regression A regression from a previous release label May 31, 2021
@christophstrobl
Copy link
Member

Types having a write Converter are considered custom simple types. The change introduced via spring-projects/spring-data-commons#2293 takes this into account when evaluating the property path.
I need to take this to the team to see if we fix this in the MongoDB module only or if it requires a broader solution for all modules.

christophstrobl added a commit that referenced this issue Jun 1, 2021
spring-projects/spring-data-commons#2293 changed how PersistentProperty paths get resolved and considers potentially registered converters for those, which made the path resolution fail in during the query mapping process.
This commit makes sure to capture the according exception and continue with the given user input.

Fixes: #3659
@jnaalisv
Copy link

jnaalisv commented Jun 13, 2021

We are also hitting this when trying to execute MongoTemplate.updateMulti:

org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for property private [redacted]

    	at org.springframework.data.mapping.context.MappingContext.getRequiredPersistentEntity(MappingContext.java:152)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPair(PersistentPropertyPathFactory.java:225)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.createPersistentPropertyPath(PersistentPropertyPathFactory.java:199)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.lambda$getPersistentPropertyPath$1(PersistentPropertyPathFactory.java:172)
    	at java.base/java.util.concurrent.ConcurrentMap.computeIfAbsent(ConcurrentMap.java:330)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.getPersistentPropertyPath(PersistentPropertyPathFactory.java:171)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:86)
    	at org.springframework.data.mapping.context.PersistentPropertyPathFactory.from(PersistentPropertyPathFactory.java:99)
    	at org.springframework.data.mapping.context.AbstractMappingContext.getPersistentPropertyPath(AbstractMappingContext.java:285)
    	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.getPath(QueryMapper.java:1183)
    	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1045)
    	at org.springframework.data.mongodb.core.convert.QueryMapper$MetadataBackedField.<init>(QueryMapper.java:1022)
    	at org.springframework.data.mongodb.core.convert.UpdateMapper$MetadataBackedUpdateField.<init>(UpdateMapper.java:298)
    	at org.springframework.data.mongodb.core.convert.UpdateMapper.createPropertyField(UpdateMapper.java:257)
    	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:144)
    	at org.springframework.data.mongodb.core.convert.UpdateMapper.getMappedObject(UpdateMapper.java:68)
    	at org.springframework.data.mongodb.core.convert.QueryMapper.convertSimpleOrDocument(QueryMapper.java:520)
    	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedKeyword(QueryMapper.java:364)
    	at org.springframework.data.mongodb.core.convert.QueryMapper.getMappedObject(QueryMapper.java:138)
    	at org.springframework.data.mongodb.core.convert.UpdateMapper.getMappedObject(UpdateMapper.java:68)
    	at org.springframework.data.mongodb.core.QueryOperations$UpdateContext.getMappedUpdate(QueryOperations.java:776)
    	at org.springframework.data.mongodb.core.MongoTemplate.doUpdate(MongoTemplate.java:1642)
    	at org.springframework.data.mongodb.core.MongoTemplate.updateMulti(MongoTemplate.java:1583)

This blocks upgrades to Spring Boot 2.5.X. Hope the fix gets merged soon.

@jnaalisv
Copy link

@IsNull Thanks for reporting this!

mp911de pushed a commit that referenced this issue Jun 18, 2021
Fix typo in class name and make sure MongoTestTemplate uses the configured simple types.
Remove superfluous junit extension.

See: #3659
Original pull request: #3661.
mp911de pushed a commit that referenced this issue Jun 18, 2021
spring-projects/spring-data-commons#2293 changed how PersistentProperty paths get resolved and considers potentially registered converters for those, which made the path resolution fail in during the query mapping process.
This commit makes sure to capture the according exception and continue with the given user input.

Fixes: #3659
Original pull request: #3661.
mp911de pushed a commit that referenced this issue Jun 18, 2021
Fix typo in class name and make sure MongoTestTemplate uses the configured simple types.

See: #3659
Original pull request: #3661.
mp911de pushed a commit that referenced this issue Jun 18, 2021
spring-projects/spring-data-commons#2293 changed how PersistentProperty paths get resolved and considers potentially registered converters for those, which made the path resolution fail in during the query mapping process.
This commit makes sure to capture the according exception and continue with the given user input.

Fixes: #3659
Original pull request: #3661.
mp911de pushed a commit that referenced this issue Jun 18, 2021
Fix typo in class name and make sure MongoTestTemplate uses the configured simple types.

See: #3659
Original pull request: #3661.
@mp911de mp911de added this to the 3.1.10 (2020.0.10) milestone Jun 18, 2021
@mp911de mp911de removed the status: feedback-provided Feedback has been provided label Jun 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A regression from a previous release
Projects
None yet
5 participants