spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.61k stars 1.08k forks source link

Support instantiation of Kotlin class with overridden read-only property #4485

Closed ederfmatos closed 1 week ago

ederfmatos commented 1 year ago

I have the following data class in kotlin, where the "type" attribute always has the fixed value "BILLET", this is because the interface that my class implements asks for this attribute.

data class BilletTransaction(
    override val id: String,
    override val name: TransactionName,
    override val createdAt: ZonedDateTime,
    override val value: BigDecimal,
    val dueDate: LocalDate,
) : Transaction {
    override val type: TransactionType = TransactionType.BILLET
}

I have a record in the mongo database with this information, but when trying to read it I get the following error:

java.lang.UnsupportedOperationException: No accessor to set property private final transient <PACKAGE>.TransactionType <PACKAGE>.BilletTransaction.type
    at <PACKAGE>.BilletTransaction_Accessor_wa9qij.setProperty(Unknown Source)
    at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:81)
    at org.springframework.data.mapping.model.ConvertingPropertyAccessor.setProperty(ConvertingPropertyAccessor.java:60)
    at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readProperties(MappingMongoConverter.java:606)

I noticed that in the class "InstantiationAwarePropertyAccessor" there is a method that tries to use a possible "setter" to configure the value, but it is not possible and the error occurs

image

Is it possible to get around this error?

ederfmatos commented 1 year ago

Using Transient annotation this problem is fixed, but the value of field is not saved in the database. In this case, the field is no writable field, is read only

mp911de commented 1 year ago

The root of this is that we should refrain from reading immutable properties in the first place. Generally speaking, if the field in your domain model is set to a fixed value, it doesn't make sense to write it to the database.

As MappingMongoConverter is attempting to read a value for an immutable property, we should rather attempt to filter out such properties from being read.