kmongo icon indicating copy to clipboard operation
kmongo copied to clipboard

Sealed interface not serializable without custom polymorphic module

Open zigzago opened this issue 2 years ago • 4 comments

zigzago avatar May 13 '22 13:05 zigzago

see https://github.com/Litote/kmongo/issues/310

zigzago avatar May 13 '22 13:05 zigzago

Hi, this seems fixed on the serialization side (at least, using ktx serialization v 1.6.0), but, it does not seem to deserialize back out when attempting to read from DB.

For example, I can store a sealed interface no problem

@Serializable
sealed interface SchemaEntity {
  val id: Id<SchemaEntity>
  val namespaceId: String
  val name: String
  val description: String
  fun toSchema(): Schema

  companion object {
    fun fromSchema(schema: Schema): SchemaEntity = when (schema) {
      is EnumSchema -> EnumSchemaEntity.fromSchema(schema)
      is ObjectSchema -> ObjectSchemaEntity.fromSchema(schema)
    }
  }
}

@Serializable
data class EnumSchemaEntity(
  @Contextual @SerialName("_id")
  override val id: Id<SchemaEntity> = newId(),
  // ...

I can see it in my DB

Screenshot 2023-09-03 at 3 40 42 PM

However, any attempt to read (deserialize) results in the following :(

2023-09-03 15:37:53.100 [Thread-15] DEBUG org.mongodb.driver.operation - Unable to retry the operation find due to the error "com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.rippling.sdog.persistence.entity.schema.SchemaEntity` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: de.undercouch.bson4jackson.io.LittleEndianInputStream@4b65b5e8; pos: 0]"
2023-09-03 15:37:53.103 [DefaultDispatcher-worker-3] DEBUG ktor.application - Unhandled: GET - /schema. Exception class com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.rippling.sdog.persistence.entity.schema.SchemaEntity` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: de.undercouch.bson4jackson.io.LittleEndianInputStream@4b65b5e8; pos: 0]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.rippling.sdog.persistence.entity.schema.SchemaEntity` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: de.undercouch.bson4jackson.io.LittleEndianInputStream@4b65b5e8; pos: 0]

Is there any workaround for this?

brizzbuzz avatar Sep 03 '23 19:09 brizzbuzz

As I'm looking at the serialized result, I am wondering... is it using KTX at all? b/c the approach that ktx serialization uses is to attach a type key to the payload, which is a fully qualified classname, so the object can be serialize / deserialized to the correct type.

Maybe I have just not configured my kmongo correctly to use ktx serialization?

brizzbuzz avatar Sep 03 '23 19:09 brizzbuzz

ooh I see kmongo is deprecated now 👀 👀

Going to explore the official driver, thanks so much for building this and maintaining it all this time :)

brizzbuzz avatar Sep 03 '23 19:09 brizzbuzz