I'm getting Exception is kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for missing class discriminator ('null').
@kotlinx.serialization.Serializable
abstract class BaseShape
@kotlinx.serialization.Serializable
class Rectangle(
val edges: Int
) : BaseShape()
@kotlinx.serialization.Serializable
internal data class Test(
val name: String,
val shape: BaseShape,
)
``` kotlin
val testData = Json {
ignoreUnknownKeys = true
prettyPrint = true
}.decodeFromString
I'm trying to deserialize the json to get `Test` object. And here it's my json;
``` json
{
"name": "Lorem Ipsum",
"shape": {
"edges": 4
}
}
Environment
Could you please show the code how you serialize and deserialize instances of the Test class?
I've updated the issue. @shanshin
If you using an abstract class for shape polymorphic serialization then expected a special discriminator column with information about the concrete type of shape property.
e.g. for classes
@kotlinx.serialization.Serializable
abstract class BaseShape
@kotlinx.serialization.Serializable
@SerialName("Rectangle")
class Rectangle(
val edges: Int
) : BaseShape()
@kotlinx.serialization.Serializable
internal data class Test(
val name: String,
val shape: BaseShape,
)
deserialization will be looks like
val module = SerializersModule {
polymorphic(BaseShape::class) {
subclass(Rectangle::class, Rectangle.serializer())
}
}
val testData = Json {
serializersModule = module
ignoreUnknownKeys = true
prettyPrint = true
}.decodeFromString<Test>(jsonString)
and valid JSON is
{
"name": "Lorem Ipsum",
"shape": {
"type": "Rectangle",
"edges": 4
}
}
see https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md#open-polymorphism
After decodeFromString<Test>(jsonString), shape is BaseShape not Rectangle 馃槙
val jsonString = """{
"name": "Lorem Ipsum",
"shape": {
"type": "Rectangle",
"edges": 4
}
}"""
val testData = Json {
serializersModule = module
ignoreUnknownKeys = true
prettyPrint = true
}.decodeFromString<Test>(jsonString)
println(testData.shape is Rectangle)
will prints true
Here it is the log;
2021-01-12 00:42:14.193 7283-9169/com.yekta.example I/CustomController: Test(name=Lorem Ipsum, shape=com.yekta.example.data.BaseShape@f18051d)
2021-01-12 00:42:14.193 7283-9169/com.yekta.example I/CustomController: false
com.yekta.example.data.BaseShape@f18051d
In your example BaseShape is abstract, it can't be instantiated.
Can you show the actual code for classes and deserialization?
Sorry my bad. Now, it works. Thank you @shanshin.