Lets say there is abstract class BaseClass ...
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable(with = PolymorphicSerializer::class)
abstract class BaseClass {
@SerialName("bid")
var baseId: String? = null
}
... class ExtendedClass that extends it ...
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
class ExtendedClass
(@SerialName("eid")
var newId: String? = null
) : BaseClass()
... and PolymorphicSerializer
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.json.JsonContentPolymorphicSerializer
import kotlinx.serialization.json.JsonElement
object PolymorphicSerializer : JsonContentPolymorphicSerializer<BaseClass>(BaseClass::class) {
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<out BaseClass> {
return ExtendedClass.serializer()
}
}
PolymorphicSerializer is used because JSON can be deserialized as different classes that extend BaseClass based on some property (for sake of simplicity I just used ExtendedClass.serializer() )
Now, if we try to deserialize generic JSON to ExtendedClass ...
class DeserializationTest {
@Test
fun deserialization_isCorrect() {
val extendedClass = Json {
ignoreUnknownKeys = true
}.decodeFromString<BaseClass>("""{"bid":"bid","eid":"eid"}""")
assertEquals("bid", extendedClass.baseId)
}
}
... test fails
java.lang.AssertionError:
Expected :bid
Actual :null
If I try to serialize ExtendedClass ...
val extendedClass = ExtendedClass()
extendedClass.baseId = "bid"
extendedClass.newId = "eid"
val encodedJson = Json {
ignoreUnknownKeys = true
}.encodeToString(extendedClass)
I can see encodedJson is {"eid":"eid"} but if I remove JsonContentPolymorphicSerializer this works fine (replace @Serializable(with = PolymorphicSerializer::class) with @Serializable ), encodedJson is {"bid":"bid","eid":"eid"}
So, for some reason JsonContentPolymorphicSerializer does not take into account properties from super class.
Anyone knows why is that so?