mongodb - 在 Kotlin 中,为什么 jackson 在某些情况下无法解码非注释对象而不是在其他情况下

标签 mongodb jackson kotlin jongo jackson-modules

我正在使用 Kotlin 和 Jongo 来访问 MongoDB。 Jongo 使用 Jackson 序列化/反序列化对象,以便从 MongoDB 中保存和读取它们。我使用 Jackson-Kotlin 模块来帮助使用构造函数序列化 Kotlin 数据类。

这是一个可以很好地序列化的数据类的示例:

data class Workflow (
    @field:[MongoId MongoObjectId] @param:MongoId
    var id: String? = null,

    val name: String,
    val states: Map<String, State>
)

这是一个无法反序列化的类似类的示例:
data class Session (
    @field:[MongoObjectId MongoId] @param:MongoId
    var id: String? = null,

    var status: CallStatus,
    var currentState: String,
    var context: MutableMap<String, Any?>,
    val events: MutableMap<String, Event>
)

Jongo 抛出以下异常,因为 Jackson 反序列化失败:
org.jongo.marshall.MarshallingException: Unable to unmarshall result to class example.model.Session from content { "_id" : { "$oid" : "56c4976aceb2503bf3cd92c2"} , "status" : "Ongoing" , "currentState" : "Start" , "context" : { } , "events" : { }}
... bunch of stack trace entries ...
Caused by: java.lang.IllegalArgumentException: Argument #1 of constructor [constructor for example.model.Session, annotations: [null]] has no property name annotation; must have name when multiple-parameter constructor annotated as Creator

如果我像这样完全注释 Session 数据类,它确实有效:
data class Session (
    @field:[MongoObjectId MongoId] @param:MongoId
    var id: String? = null,

    @JsonProperty("status")
    var status: CallStatus,

    @JsonProperty("currentState")
    var currentState: String,

    @JsonProperty("context")
    var context: MutableMap<String, Any?>,

    @JsonProperty("events")
    val events: MutableMap<String, Event>
}

我的问题是,为什么它适用于 Workflow?当 Session 数据类没有完全注释时,导致解码失败的细微差别是什么?

编辑

不同之处在于我测试了从 Gradle 运行它的 Workflow 测试用例,它使用了不同版本的 Kotlin,然后是我从 IDEA IDE 运行的 Session 测试用例。 IDEA 的 Kotlin 插件的更新也更新了 IDEA 用来运行测试用例的 Kotlin 版本,我没有注意到。这导致 Kotlin 和 Jackson-Kotlin 库的版本不匹配。下面接受的答案指出了需要配置什么才能让事情再次运行。

最佳答案

如果 MongoDB 使用 ObjectMapper,您将收到此错误。没有在其中注册 Jackson-Kotlin 模块。您的 JsonProperty注释基本上与模块隐式执行的操作相同。但如果它不存在,您将收到大致相同的错误消息。

要看的东西:

  • 您拥有与您的 Kotlin 代码版本相匹配的 Jackson-Kotlin 模块兼容版本。对于 RC 1050 或更新版本,您需要 README.MD file on GitHub 中提到的最新版本的 Jackson 模块。 .

    Older versions of the Jackson-Kotlin module are not compatible with Kotlin 1.0.0. You must update or you will have silent failures (the module cannot recognize a Kotlin class, so ignores it). Releases for Kotlin 1.0.0 will be available on Maven Central shortly. In the meantime use the EAP repository:

    maven {
       url  "http://dl.bintray.com/jaysonminard/kohesive"
    }
    

    For Kotlin 1.0.0, use one of:

    • release 2.7.1-1 (for Jackson 2.7.x)
    • release 2.6.5-2 (for Jackson 2.6.x)
    • release 2.5.5-2 (for Jackson 2.5.x)

    Later this will move back to Maven Central.

  • 发送给 jackson 的实际 JSON 是什么
  • 这个错误是来自堆栈跟踪中的 MongoDB,还是肯定涉及 Jackson(它在调用 Jackson 之前是否预处理并确定错误)?
  • MongoDB 是如何获得它的 ObjectMapper 的,你是如何尝试配置它的?
  • 关于mongodb - 在 Kotlin 中,为什么 jackson 在某些情况下无法解码非注释对象而不是在其他情况下,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35461960/

    相关文章:

    kotlin - GraphQL服务器端流式实现

    node.js - 将时间戳添加到 mongoose 中的新子文档或子模式

    java - Jackson 反/序列化 Key 问题

    java - 如何让 Jackson 序列化器更加 DRY?

    android - 如何从 Jetpack Compose TextField 关闭虚拟键盘?

    c - Doom 如何从现有的正弦查找表中确定其余弦查找表?

    mongodb - MongoError:无效的$project::由::未知表达式$dateSubtract引起

    mongodb - 如何从 MongoDB 数据库中删除用户

    mongodb - Mongodb - 查询嵌套数组和对象

    Jackson无法反序列化(Spring Cloud Stream Kafka)