jackson-module-kotlin
jackson-module-kotlin copied to clipboard
@JsonValue not working for root
Describe the bug
@JsonValue annotation on top node work correctly during serialization but fault on deserialization.
Version information
Latest
To Reproduce
val mapper = jacksonMapper()
data class A(@JsonValue val a: List<String>)
val s=mapper.writeValueAsString(A(listOf("A")) // OK: ["A"]
mapper.readValue(s,A::class.java) // boom!
Additional context
I use Kotlin.
I am not sure this is a bug as there is nothing automatic wrt @JsonValue on deserialization: it is not designed to have any effect on deserialization of POJOs... although Enums do have bit of special handling.
Typically you'd need to use @JsonCreator with mode = JsonCreator.Mode.DELEGATING (NOT properties) to make deserialization work.
So I think that's what is missing here.
But since this is Kotlin-specific, I will first move it to appropriate module.
Thinking about this a bit more, I realized that maybe @JsonValue on single constructor/factory method argument SHOULD imply "delegating" creator. And sent a question on jackson-dev list to see if others agree.
This might, in future, allow usage like above (I am not 100% how Kotlin compiler associates annotations to know if it could "just" work). But I think this might be bit more readable than using @JsonCreator(mode = ).
@cowtowncoder thank for your work.
@cpdyj Expanding on the DELEGATING mode which is what I've used:
val mapper = jacksonObjectMapper()
data class A @JsonCreator(mode = JsonCreator.Mode.DELEGATING) constructor(@JsonValue val a: List<String>)
val s = mapper.writeValueAsString(A(listOf("A")))
mapper.readValue(s, A::class.java)
Automatically make it work with @JsonValue would be nice, though.