Description
After updating to Spring Boot 3.2, my Kotlin app does not start anymore with an exception of Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'queryLookupStrategyKey' of bean class [com.example.demo.JpaRepositoryFactoryBeanImpl]: Bean property 'queryLookupStrategyKey' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
.
After debugging for some time I found out that in 3.2 there seems to be some new property introspection for kotlin classes and their properties are active. The problem seems to be, that the setters from the super class, in that case JpaRepositoryFactoryBean
are not recognized as they are not Kotlin properties.
I can work around that by including the following code:
private var queryLookupStrategyKey: Key
get() = throw UnsupportedOperationException()
@JvmName("setQueryLookupStrategyKeyKt") set(value) {
super.setQueryLookupStrategyKey(value)
}
private var lazyInit: Boolean
get() = throw UnsupportedOperationException()
@JvmName("setLazyInitKt") set(value) {
super.setLazyInit(value)
}
private var namedQueries: NamedQueries
get() = throw UnsupportedOperationException()
@JvmName("namedQueriesKt") set(value) {
super.setNamedQueries(value)
}
private var repositoryFragments: RepositoryFragments
get() = throw UnsupportedOperationException()
@JvmName("setRepositoryFragmentsKt") set(value) {
super.setRepositoryFragments(value)
}
private var transactionManager: String
get() = throw UnsupportedOperationException()
@JvmName("setTransactionManagerKt") set(value) {
super.setTransactionManager(value)
}
private var entityManager: EntityManager
get() = throw UnsupportedOperationException()
@JvmName("setEntityManagerKt") set(value) {
super.setEntityManager(value)
}
private var escapeCharacter: Char
get() = throw UnsupportedOperationException()
@JvmName("setEscapeCharacterKt") set(value) {
super.setEscapeCharacter(value)
}
private var mappingContext: MappingContext<*, *>
get() = throw UnsupportedOperationException()
@JvmName("setMappingContextKt") set(value) {
super.setMappingContext(value)
}
private var enableDefaultTransactions: Boolean
get() = throw UnsupportedOperationException()
@JvmName("setEnableDefaultTransactionsKt") set(value) {
super.setEnableDefaultTransactions(value)
}
Another workaround is writing that class in java, but this defeats the purpose of using Kotlin in the first place.
Attached is a minimal reproducible example: kotlin-jpa-bug.zip