I have typed inline value class for typed identification…
@JvmInline
@Serializable
value class Id<T>(
@Contextual
val value: ObjectId = ObjectId()
)
I use this class on all my domain models…
@Serializable
data class Test(
override var _id: Id<Test> = Id(),
val value: String,
)
@Serializable
data class Status(
override var _id: Id<Status> = Id(),
var test_id: Id<Test>,
val value: String
)
...
The database seeding goes well everything works as expected, I see documents in the right form… But when I’m trying to read from database it creates this error…
org.bson.codecs.configuration.CodecConfigurationException:
Can't find a codec for CodecCacheKey{clazz=class Id, types=null}.
Does anyone have a clue how to write Codec for typed value classes because I have no idea?
You have to define codec class for your generic class and use star operator on generic type…
class IdCodec : Codec<Id<*>> {
override fun encode(writer: BsonWriter, value: Id<*>, encoderContext: EncoderContext) {
return writer.writeObjectId(value.value)
}
override fun decode(reader: BsonReader, decoderContext: DecoderContext): Id<*> {
return Id<Any>(value = reader.readObjectId())
}
override fun getEncoderClass(): Class<Id<*>> = Id::class.java
}
Then register this codec on created database instance…
val idCodecRegistry = CodecRegistries.fromCodecs(IdCodec())
var codecRegistry = CodecRegistries.fromRegistries(
MongoClientSettings.getDefaultCodecRegistry(),
idCodecRegistry
)
val db = mongoClient.getDatabase(db_name).withCodecRegistry(codecRegistry)