spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.2k stars 40.69k forks source link

Spring boot 3.2.x broke mongo mapping #39531

Closed mmuruev closed 9 months ago

mmuruev commented 9 months ago

I'm not quite sure what was the reason, but after upgraged from 3.1.x I've got this at tests runtime

 Parameter org.springframework.data.mapping.Parameter@107c37d1 does not have a name
org.springframework.data.mapping.MappingException: Parameter org.springframework.data.mapping.Parameter@107c37d1 does not have a name
    at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:61)
    at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49)
    at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:301)
    at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:273)
    at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:519)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:487)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:423)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:419)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:119)
    at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3278)
    at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2912)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2592)
    at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2573)
    at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:866)
    at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:821)
    at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:804)

And yes debugger says no name or anything useful in the object. Cant find mention about this issue, may be it is a bug. I'm using Kotlin 1.9.22. Project setup the same as initiazer suggests.

wilkinsona commented 9 months ago

You need to compile with parameter information enabled. If you're using Spring Boot's Gradle plugin or spring-boot-starter-parent with Maven, it should enable the javaParameters option on Kotlin's compiler automatically. If the entity's in another module, you'll have to configure this manually.

mmuruev commented 9 months ago

Yes, but if I have to do so why initializer offers no such thing? I think if it do so (probably with comment) it will be quite nice and obvious, for now from error you cant say what actually went wrong.

wilkinsona commented 9 months ago

In a single-module project generated by https://start.spring.io, the necessary Kotlin compiler configuration should come from Spring Boot's Gradle plugin for Gradle projects or from spring-boot-starter-parent for Maven projects. In other words, there's no need for Initializr to offer anything here as it should be configured automatically. If that's not working for you and you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

slow-groovin commented 8 months ago

I have the same issues, and solve it by downgrade from 3.2.3 to 3.1.9, the scene is:

wilkinsona commented 8 months ago

@slow-groovin there should be no need to downgrade, but you do have to make sure that the code is being compiled with -parameters. In a single-module project using Spring Boot's Gradle plugin or inheriting from spring-boot-starter-parent, that should happen automatically. As I said above, if that's not working for you and you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

slow-groovin commented 8 months ago

@wilkinsona Thank you. I have tried different conditions, finally find the problem is caused specificly:

any of above changes different will has no problem:

The last two conditions seems strange, if these behaviors exceed design expectations, u can have a look at my sample: probelm-reproduce.zip Please search for HINT in projects for my explain.

wilkinsona commented 8 months ago

Thanks. Those last two conditions are beyond my knowledge of the inner-workings of Spring Data MongoDB. At a guess, they change how it behaves such that parameter name information isn't required.

/cc @mp911de @christophstrobl from the Spring Data team for awareness.

christophstrobl commented 8 months ago

The data infrastructure requires parameter names to be present. Using lombok @Builder only creates a constructor with both arguments for the inner type, but no no-arg constructor as the @Data annotation does. That explains why it fails for the one and works for the other. In the @Data scenario spring-data can fall back to using the no args constructor to instantiate the type without the need of parameter names being present.