问题描述
我有一个 Java EE 项目,它使用 JOOQ 使用 Kotin 自动生成记录。
这样的记录是:
@Suppress("UNCHECKED_CAST")
open class EmailAddressRecord() : UpdatableRecordImpl<EmailAddressRecord>(EmailAddress.EMAIL_ADDRESS),Record5<Int?,Int?,String?,Boolean?,Boolean?> {
//...
var isInList: Boolean?
set(value) = set(3,value)
get() = get(3) as Boolean?
当通过 GET
方法发送到客户端时,记录会按预期序列化为类似 { "isInList": true }
的 json。
但是如果我将它发送回 PUT
方法,我会收到一个关于 isInList
未被识别的错误。相反,如果我发送一个带有 inList
属性的 json(没有 is
),则记录会在服务器端正确反序列化。
涉及几个方面,所以我什至不确定是哪个导致了问题:
- 也许是因为 JOOQ 如何使用
var
生成记录 - 也许是 Wildfly / RestEasy 做了一些时髦的事情
- 也许是 Jackson 没有正确反序列化记录(我曾尝试添加 jackson kotlin 模块,但似乎没有任何区别)
任何指针将不胜感激。
版本:jackson 2.12.2、kotlin 1.4.10、widlfly 10、jooq 3.14.10
解决方法
这是在 jOOQ 3.15.0 和 3.14.12 中实施的修复的扩展:https://github.com/jOOQ/jOOQ/issues/11912
问题是 kotlin 为名为 setInList()
的可变属性生成 isInList
setter,而不是 setIsInList()
。在上述问题中,这可能与 inList
属性的同名 setter 发生冲突:
class X {
var inList: Boolean?
var isInList: Boolean?
}
我不相信这在 jOOQ 情况下是一个有用的优化。我们可以始终在以 @set:JvmName("...")
开头的列的属性上生成 IS_
注释,而不是仅在出现上述名称冲突时才修复 #11912:
class X {
@set:JvmName("setIsInList")
var isInList: Boolean?
}
当然,还要使其可配置。从 jOOQ 3.15.0 开始,可以通过指定以下内容来关闭这些注释:
<kotlinSetterJvmNameAnnotationsOnIsPrefix>false</kotlinSetterJvmNameAnnotationsOnIsPrefix>