Since Kotlin data classes are already constructed with values we don't want to override all the properties later on again. Properties modified in the init { } block in a class would be reverted back to the value of the column again.
An example of this would be setting the default scale of a BigDecimal inside an init block. The init would be called and set the scale after constructing. However, after constructing the BeanPropertyRowMapper would override the BigDecimal again so the scale would be 0 again.
This commit fixes this issue for Kotlin data classes.
Comment From: dennie170
Hi team, I see nobody has replies to my issue since February. Are you gonna have a look at this? It is pretty "breaking" in Kotlin, and now demands some custom solutions. Thanks!
Comment From: jhoeller
It turns out that Kotlin var
declarations implicitly generate setter methods for the affected properties, which leads to our DataClassRowMapper
populating that setter as well (since we're expecting either a constructor argument or a setter method, not both, we haven't been checking for this explicitly). Mixing and matching between constructor arguments and setter methods is allowed by design, so we can't cut off the latter completely (like the original PR does). Instead, I've revised the DataClassRowMapper
algorithm to suppress setter method calls for all properties that have been populated through constructor arguments already. In addition to a Java-based test for this behavior, I've also added your Kotlin test case.
Thanks for the PR, in any case!
Comment From: dennie170
Thanks for figuring it out and the clear explanation! Glad to see it's fixed now.