Environment: Spring-boot 2.1.2.RELEASE, Spring-data 2.1.4.RELEASE, Kotlin 1.2.x ~ 1.3.x, Mongodb.
I defined a model class like:
@Document
class MeAccount : Setting() {
lateinit var id: String
val accountEntries = listOf<BankAccount>()
}
When I tried to read this model from mongodb, I got exception stacktrace blow:
java.lang.UnsupportedOperationException: No accessor to set property private final java.util.List com.xxx.MeCustodianAccount.accountEntries!
at com.xxx.MeCustodianAccount_Accessor_fs514j.setProperty(Unknown Source)
at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:61)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:378)
For attention, the code works fine with spring-boot 1.5.x and spring-data 1.x.
What can I do to solve this issue? Seems many similar exception reports below:
Spring boot 2.1.0 security change with kotlin data class?
https://github.com/arangodb/spring-data/issues/123
https://github.com/spring-projects/spring-boot/issues/15698
[Resolved] Works after fall back to Spring-boot 2.0.x and spring-data-commons 2.0.x. Will keep 2.1 excluded in future upgrading plans.
Spring Data in 2.1. has changed the way in which it deals with final fields in entities. It no longer uses reflection to override the immutability of the fields, which in general is good. There are a few ways to cope with the problem.
They are described here: https://jira.spring.io/browse/DATACMNS-1374?focusedCommentId=182289&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-182289
Here's what the Spring guys recommend:
- Add a @PersistenceConstructor to construct the entity that sets immutable fields.
- Add wither methods (MyEntity withXxx(…)) to create a new instance that contains the changed property value.
- Alternatively: Use Kotlin's data class feature. This will basically do the same as wither methods.
So for you should work something like this:
@Document
data class MeAccount(val id: String, val accountEntries: List<Price>) : Setting()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With