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

Posted

技术标签:

【中文标题】JOOQ 类中的布尔字段未由 Jackson/RestEasy 一致地序列化和反序列化【英文标题】:Boolean fields in JOOQ classes not serialized and deserialized consistenly by Jackson/RestEasy 【发布时间】:2021-08-26 02:56:55 【问题描述】:

我有一个 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 方法,我会收到关于 isInListnot 被识别的错误。相反,如果我发送带有 inList 属性(没有 is)的 json,则记录会在服务器端正确反序列化。

涉及到几个问题,所以我什至不确定是哪个导致了问题:

可能是因为 JOOQ 如何使用var 生成记录 也许是 Wildfly / RestEasy 在做一些时髦的事情 也许是 Jackson 没有正确反序列化记录(我尝试添加 jackson kotlin 模块,但似乎没有任何区别)

任何指针将不胜感激。

版本:jackson 2.12.2、kotlin 1.4.10、widlfly 10、jooq 3.14.10

【问题讨论】:

让我想起了github.com/jOOQ/jOOQ/issues/11912。如果您使用 @set:JvmName("setIsInList") 注释属性会发生什么? 是的,解决了问题,做得很好!即使不理想,因为它将在每个代码生成中被删除。我可以看到您使用类似的方法来解决问题。我可能只需要提高 JOOQ 版本。 啊,14.12 还没有在 Central 推出 :-) 您可以在代码生成后将其实现为正则表达式搜索替换后处理器。 #11912 不是同一个问题,而是相关的。在kotlin中,如果一个可变属性x存在,那么就不能再有另一个可变属性isX,否则生成的setter会出现名字冲突。我认为这个is 魔法是 kotlin 语言设计缺陷,不管有没有 jOOQ,人们都会遇到这个问题。无论如何,我想知道我们是否应该总是在以is...开头的属性上生成该注释? @LukasEder 感谢您提供正则表达式提示。至于你的最后一个问题,在我的情况下它可以正常工作,但我不知道它是否会破坏其他人的东西...... 【参考方案1】:

这是在 jOOQ 3.15.0 和 3.14.12 中实现的修复的扩展:https://github.com/jOOQ/jOOQ/issues/11912

问题是 kotlin 为名为 isInList 的可变属性生成了一个 setInList() setter,而不是 setIsInList()。在上述问题中,这可能与 inList 属性的同名设置器发生冲突:

class X 
  var inList: Boolean?
  var isInList: Boolean?

我不相信这在 jOOQ 案例中是一个有用的优化。与其仅在出现上述名称冲突时修复 #11912,我们还可以始终在以 IS_ 开头的列的属性上生成 @set:JvmName("...") 注释:

class X 
  @set:JvmName("setIsInList")
  var isInList: Boolean?

当然,还要让它可配置。从 jOOQ 3.15.0 开始,可以通过指定以下内容来关闭这些注释:

<kotlinSetterJvmNameAnnotationsOnIsPrefix>false</kotlinSetterJvmNameAnnotationsOnIsPrefix>

【讨论】:

以上是关于JOOQ 类中的布尔字段未由 Jackson/RestEasy 一致地序列化和反序列化的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ自动生成的类中字段的SQLDataType有啥用

JOOQ:根据长度将 tinyint 映射到布尔值

jOOQ:比较 uuid(来自 postgresql)和字符串(类中的用户 id)

如何使用 jOOQ gradle 插件将 postgres 中的 bigint[] 字段转换为类字段

Scala:使用带有布尔方法的 jOOQ DSL

使用 JOOQ 查询 mysql 中的 json 字段