spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.

Home Page:https://spring.io/projects/spring-data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Apply Kotlin Value Class unboxing to generated Property Accessors

mp911de opened this issue · comments

Providing a boxed value type via reflection works while using generated property accessors fails when the underlying type uses a unboxed representation.

@JvmInline
value class Auditor(val str: String)

data class MyEntity(
    @Id val id: Long = 0L,
    val name: String,
    @CreatedBy val createdBy: Auditor = Auditor("UNKNOWN"),
)

@Configuration
@EnableR2dbcAuditing
class AuditConfig {
    @Bean
    fun auditorAware(): ReactiveAuditorAware<Auditor> = ReactiveAuditorAware {
        Auditor("test")
    }
}

In Spring Data 3.2.5, when setting audit parameters, exception throws like

java.lang.ClassCastException: class mypackage.Auditor cannot be cast to class java.lang.String (mypackage.Auditor is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')
	at mypackage.MyEntity_Accessor_uf7rrw.setProperty(Unknown Source)
	at org.springframework.data.mapping.model.ClassGeneratingPropertyAccessorFactory$KotlinValueBoxingAdapter.setProperty(ClassGeneratingPropertyAccessorFactory.java:1451)
	at org.springframework.data.mapping.model.InstantiationAwarePropertyAccessor.setProperty(InstantiationAwarePropertyAccessor.java:80)
	at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:108)
	at org.springframework.data.mapping.model.SimplePersistentPropertyPathAccessor.setProperty(SimplePersistentPropertyPathAccessor.java:127)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.lambda$setProperty$0(MappingAuditableBeanWrapperFactory.java:232)
	at java.base/java.lang.Iterable.forEach(Iterable.java:75)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setProperty(MappingAuditableBeanWrapperFactory.java:232)
	at org.springframework.data.auditing.MappingAuditableBeanWrapperFactory$MappingMetadataAuditableBeanWrapper.setLastModifiedBy(MappingAuditableBeanWrapperFactory.java:207)
	at org.springframework.data.auditing.AuditingHandlerSupport.touchAuditor(AuditingHandlerSupport.java:173)
	at org.springframework.data.auditing.AuditingHandlerSupport.lambda$touch$0(AuditingHandlerSupport.java:136)
	at java.base/java.util.Optional.map(Optional.java:260)
	at org.springframework.data.auditing.AuditingHandlerSupport.touch(AuditingHandlerSupport.java:134)
	at org.springframework.data.auditing.AuditingHandlerSupport.markModified(AuditingHandlerSupport.java:127)
	at org.springframework.data.auditing.ReactiveAuditingHandler.lambda$markModified$1(ReactiveAuditingHandler.java:90)
        ...

Originally posted by @w3-3w in #2868 (comment)