I have a problem with objects mapping after migrating to Spring Boot 2.4. So far I was using Spring Boot 2.3 (with Kotlin).
For the sample database query
override fun findMyEntities(searchParams: SearchParams): Flux<MyEntity> =
databaseClient
.sql("SELECT * FROM my_entities ........................... OFFSET :offset LIMIT :limit")
.bind("searchPhrase", searchParams.searchPhrase)
.bind("limit", searchParams.pageSize)
.bind("offset", searchParams.offset)
.map(::mapRow)
.all()
private fun mapRow(row: Row) = MyEntity(
id = row.get("id", UUID::class.java)!!,
name = row.get("name", String::class.java)!!,
description = row.get("description", String::class.java)!!,
creation = row.get("creation", UserActionMetadata::class.java)!!,
)
I'm getting errors:
Suppressed: java.lang.IllegalArgumentException: Cannot decode value of type com.mypackage.model.UserActionMetadata
at io.r2dbc.postgresql.codec.DefaultCodecs.decode(DefaultCodecs.java:153)
at io.r2dbc.postgresql.PostgresqlRow.decode(PostgresqlRow.java:90)
at io.r2dbc.postgresql.PostgresqlRow.get(PostgresqlRow.java:77)
at com.mypackage.repository.MyRepotistory.mapRow(MyRepotistory.kt:59)
Before version upgrade function above was like:
.execute("SELECT * FROM ...")
.`as`(MyEntity::class.java)
.fetch()
.all()
Where the error is happening, creation field in database is JSONB type. For that I have custom reading and writing converters (in my configuration class which extends AbstractR2dbcConfiguration).
import org.springframework.data.convert.ReadingConverter
import org.springframework.data.convert.WritingConverter
@Configuration
class DatabaseConfig(private val r2dbcProperties: R2dbcProperties, private val objectMapper: ObjectMapper) :
AbstractR2dbcConfiguration() {
@WritingConverter
inner class UserActionMetadataToJsonConverter : Converter<UserActionMetadata, Json> {
override fun convert(source: UserActionMetadata): Json {
return Json.of(objectMapper.writeValueAsString(source))
}
}
@ReadingConverter
inner class JsonToUserActionMetadataConverter : Converter<Json, UserActionMetadata> {
override fun convert(source: Json): UserActionMetadata {
return objectMapper.readValue(source.asString())
}
}
Any idea how I can successfully migrate to Spring Boot 2.4?
I have seen suggestions Spring R2DBC DatabaseClient.as(…) to use R2dbcEntityTemplate, but my queries are too complex, and code will be too bloated. There is also an issue https://github.com/spring-projects/spring-framework/issues/26021 . I hope that there is some workaround.