Kotlinx.serialization: Serializing a sealead class do not set the type field

Created on 6 Jan 2021  路  5Comments  路  Source: Kotlin/kotlinx.serialization

Describe the bug
When serializing a single object that extends a sealed class, the type field will not be set, not allowing to deserialize it as a parent calss.
To Reproduce

sealed class Parent {
  data class A(val foo: String) : Parent()
  data class B(val bar: String) : Parent()
}
val json = Json()
val a = A("hello")
val s = json.encodeToString(a)
json.decodeFromString<Parent.A>(s) // will throw

Expected behavior
Field type present in the serialized object when serializing a sealed class.

Environment

  • Kotlin version: 1.4.21
  • Library version: 1.0.1
  • Kotlin platforms: JVM
  • Gradle version: 6.7.1
question

All 5 comments

The same.

Providing the serializer manually helps:

json.encodeToString(Parent.serializer(), a)

That's intended behavior. Framework uses static (compile-time) types when available

@sandwwraith it's weird. It also breaks deserialization to a sealed class for request bodies in ktor, and seems like previously it worked correctly.

My particular use case is KMongo with Kotlinx.serialization. Specifically, even if I pass Parent as collection type, the KMongo/MongoDB drivers will check the type of the object at runtime and ignore the passed value. As such the serializer used will be either A or B.

I see @sandwwraith point tho, if you want to serialize as a polymorphic type, use the Parent serializer. Changing the behavior of Kotlinx.serialization would just be a workaround.

The same problem here: #1194

Was this page helpful?
0 / 5 - 0 ratings