Issue
I have these models
abstract class Message : Data
data class TextMessage(val m: String): Message
data class ImageMessage(val m: ByteArray): Message
and I want to get a collection by the abstract class Message
database.getCollection<Message>
But it will actually be a implement class (TextMessage, ImageMessage) instance depending on it's content
when(val value = collection.findOne()) {
is TextMessage -> {}
is ImageMessage -> {}
}
how to do this?
Solution
The KMongo library has 3 options for object mapping, and your solution will depend on which one is being used.
By default, Jackson engine is used. You can use POJO Codec engine by adding a -native suffix to the artifactId, or Kotlinx Serialization by adding a -serialization suffix to the artifactId.
https://litote.org/kmongo/quick-start/#object-mapping-engine
Depending on the engine used, apply how that engine handles polymorphism:
Jackson
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS) abstract class Message
more info: https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization
Native
@BsonDiscriminator abstract class Message
not sure if there is much more info on this but the official doc here: https://mongodb.github.io/mongo-java-driver/4.3/bson/pojos/#annotations
this essentially stores the class name under a
_t
field and gets used during deserializationkotlinx serialization
@Serializable sealed class Message @Serializable data class TextMessage(val m: String) : Message() @Serializable data class ImageMessage(val m: ByteArray) : Message()
Like jackson, there's other ways and things you may want to consider here: https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md
Answered By - Aarjav
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.