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
方法,我会收到关于 isInList
not 被识别的错误。相反,如果我发送带有 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:比较 uuid(来自 postgresql)和字符串(类中的用户 id)