JOOQ 类中的布尔字段未由 Jackson/RestEasy 一致地序列化和反序列化

问题描述

我有一个 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>