kotlin-extensions incompatible with custom serializers

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: 5.5.1
    • Component/s: Kotlin
    • None
    • Java Drivers
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      When using filters from mongodb-kotlin-extensions in combination with custom serializers from kotlinx-serialization you will run into runtime exceptions.

      Please provide the version of the driver. If applicable, please provide the MongoDB server version and topology (standalone, replica set, or sharded cluster).

      Kotlin version: 2.2.0
      org.mongodb:mongodb-driver-kotlin-coroutine:5.5.1
      org.mongodb:bson-kotlinx:5.5.1
      org.mongodb:mongodb-driver-kotlin-extensions:5.5.1

      How to Reproduce

      @file:OptIn(ExperimentalTime::class, ExperimentalSerializationApi::class)
      
      package demo.timebug
      
      import com.mongodb.kotlin.client.coroutine.MongoClient
      import com.mongodb.kotlin.client.model.Filters.eq
      import kotlin.time.Clock
      import kotlin.time.ExperimentalTime
      import kotlin.time.Instant
      import kotlinx.coroutines.runBlocking
      import kotlinx.serialization.ExperimentalSerializationApi
      import kotlinx.serialization.KSerializer
      import kotlinx.serialization.Serializable
      import kotlinx.serialization.SerializationException
      import kotlinx.serialization.descriptors.PrimitiveKind
      import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
      import kotlinx.serialization.descriptors.SerialDescriptor
      import kotlinx.serialization.encoding.Decoder
      import kotlinx.serialization.encoding.Encoder
      import org.bson.BsonDateTime
      import org.bson.BsonDocument
      import org.bson.codecs.kotlinx.BsonDecoder
      import org.bson.codecs.kotlinx.BsonEncoder
      
      @Serializable
      private data class Person(
          val name: String,
          @Serializable(with = InstantAsBsonDateTime::class)
          val birthday: Instant,
      )
      
      // example from https://www.mongodb.com/docs/drivers/kotlin/coroutine/current/fundamentals/data-formats/serialization/#custom-serializer-example
      object InstantAsBsonDateTime : KSerializer<Instant> {
          override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("InstantAsBsonDateTime", PrimitiveKind.LONG)
          override fun serialize(encoder: Encoder, value: Instant) {
              when (encoder) {
                  is BsonEncoder -> encoder.encodeBsonValue(BsonDateTime(value.toEpochMilliseconds()))
                  else -> throw SerializationException("Instant is not supported by ${encoder::class}")
              }
          }
          override fun deserialize(decoder: Decoder): Instant {
              return when (decoder) {
                  is BsonDecoder -> Instant.fromEpochMilliseconds(decoder.decodeBsonValue().asDateTime().value)
                  else -> throw SerializationException("Instant is not supported by ${decoder::class}")
              }
          }
      }
      
      fun main(): Unit = runBlocking {
          val database = MongoClient.create().getDatabase("test")
          val collection = database.getCollection<Person>("persons")
          val rawCollection = database.getCollection<BsonDocument>("persons")
      
          collection.drop()
      
          val now = Clock.System.now()
      
          collection.insertOne(Person("John Doe", now))
          rawCollection.find().collect { println(it) } // prints: {"_id": {"$oid": "6888badb86a11b04656ce4d1"}, "name": "John Doe", "birthday": {"$date": "2025-07-29T12:13:15.217Z"}}
      
          collection.find(Person::birthday eq now).collect { println(it) } // throws: Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for CodecCacheKey{clazz=class kotlin.time.Instant, types=null}.
      }
      

       

              Assignee:
              Nabil Hachicha
              Reporter:
              Richard Schielek
              None
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated: