mongodbjacksonkotlinjongojackson-modules

In Kotlin, why Jackson fails unmarshalling non-annotated object in some cases and not in others


I'm using Kotlin with Jongo to access MongoDB. Jongo uses Jackson to serialize/deserialize objects in order to save and read them from MongoDB. I use Jackson-Kotlin module to help serialize Kotlin data classes using constructors.

Here's an example of a dataclass that serializes just fine:

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

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

Here's an example of a similar class that fails to deserialize:

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>
)

Following exception is thrown by Jongo because Jackson deserialization fails:

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

It does work if I fully annotate the Session data class like this:

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>
}

My question is, why does it work for Workflow? What's the subtle difference that makes unmarshalling fail for Session data class, when it's not fully annotated?

EDIT

Difference was that I tested Workflow test case running it from Gradle, which used different version of Kotlin then the Session test case that I run from IDEA IDE. Update of IDEA's Kotlin plugin also updated Kotlin version that IDEA uses to run test cases, which I didn't notice. This resulted in mismatched versions of Kotlin and Jackson-Kotlin library. Accepted answer below pointed out what needs to be configured in order get things working again.


Solution

  • You would get this error if MongoDB is using an ObjectMapper that does not have the Jackson-Kotlin module registered into it. Your JsonProperty annotations are basically doing the same as what the module does implicitly. But if it is not present, you would receive about the same error message.

    Things to look at: