Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-5303

Unable to deserialize small values to Long when using kotlinx.serialization

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Minor - P4 Minor - P4
    • 4.11.3, 5.1.3, 5.2.0
    • Affects Version/s: None
    • Component/s: Kotlin
    • None
    • Java Drivers
    • Not Needed
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Kotlin: 1.9.22
      MongoDB Driver: 4.11.1 (mongodb-driver-kotlin-coroutine)
      BSON Kotlinx Library: 4.11.1 (bson-kotlinx)


      When following [this guide to auto-incrementing fields|https://www.mongodb.com/docs/v2.2/tutorial/create-an-auto-incrementing-field/,] let's assume we have a simple data structure like this:

       

      @Serializable
      data class Counter(
          @SerialName("_id")
          val name: String,
          val count: Long = -1,
      ) 

       

      We might create a document by using findOneAndUpdate as follows:

       

      val collection = db.getCollection<Counter>("counters")
      
      collection.findOneAndUpdate(
          Filters.eq("_id", name),
          Updates.inc("count", 1),
      
          FindOneAndUpdateOptions().upsert(true).returnDocument(ReturnDocument.AFTER)
      )!!.count 

       

      I would expect this to create a document in the current collection, and then return the count field of the resulting document. Instead, an exception is thrown:

       

      org.bson.BsonInvalidOperationException: Reading field 'count' failed expected INT64 type but found: INT32.	at org.bson.codecs.kotlinx.DefaultBsonDecoder.decodeLong(BsonDecoder.kt:295)	Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Assembly trace from producer [reactor.core.publisher.MonoCreate] :	reactor.core.publisher.Mono.create(Mono.java:202)	com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$12(OperationExecutorImpl.java:122)Error has been observed at the following site(s):	*_____Mono.create ? at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$12(OperationExecutorImpl.java:122)	|_ Mono.doOnError ? at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$12(OperationExecutorImpl.java:128)	*____Mono.flatMap ? at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.lambda$execute$13(OperationExecutorImpl.java:121)	*_______Mono.from ? at com.mongodb.reactivestreams.client.internal.OperationExecutorImpl.execute(OperationExecutorImpl.java:115)Original Stack Trace:		at org.bson.codecs.kotlinx.DefaultBsonDecoder.decodeLong(BsonDecoder.kt:295)		at kotlinx.serialization.encoding.AbstractDecoder.decodeLongElement(AbstractDecoder.kt:54)		at org.comect.auditing.storage.nosql.entities.Counter$$serializer.deserialize(Counter.kt:7)		at org.comect.auditing.storage.nosql.entities.Counter$$serializer.deserialize(Counter.kt:7)		at org.bson.codecs.kotlinx.KotlinSerializerCodec.decode(KotlinSerializerCodec.kt:182)		at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:58)		at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:87)		at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:42)		at com.mongodb.internal.connection.ReplyMessage.<init>(ReplyMessage.java:48)		at com.mongodb.internal.connection.InternalStreamConnection.getCommandResult(InternalStreamConnection.java:567)		at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendCommandMessageAsync$0(InternalStreamConnection.java:554)		at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:849)		at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:812)		at com.mongodb.internal.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:671)		at com.mongodb.internal.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:668)		at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:252)		at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:235)		at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)		at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:282)		at java.base/sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ReadTask.completed(WindowsAsynchronousSocketChannelImpl.java:581)		at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:387)		at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)		at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)		at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)		at java.base/java.lang.Thread.run(Thread.java:829)Caused by: org.bson.BsonInvalidOperationException: readInt64 can only be called when CurrentBSONType is INT64, not when CurrentBSONType is INT32.	at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:689)	at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:721)	at org.bson.AbstractBsonReader.readInt64(AbstractBsonReader.java:372)	at org.bson.codecs.kotlinx.DefaultBsonDecoder.decodeLong(BsonDecoder.kt:164)	at kotlinx.serialization.encoding.AbstractDecoder.decodeLongElement(AbstractDecoder.kt:54)	at org.comect.auditing.storage.nosql.entities.Counter$$serializer.deserialize(Counter.kt:7)	at org.comect.auditing.storage.nosql.entities.Counter$$serializer.deserialize(Counter.kt:7)	at org.bson.codecs.kotlinx.KotlinSerializerCodec.decode(KotlinSerializerCodec.kt:182)	at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:58)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:87)	at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:42)	at com.mongodb.internal.connection.ReplyMessage.<init>(ReplyMessage.java:48)	at com.mongodb.internal.connection.InternalStreamConnection.getCommandResult(InternalStreamConnection.java:567)	at com.mongodb.internal.connection.InternalStreamConnection.lambda$sendCommandMessageAsync$0(InternalStreamConnection.java:554)	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:849)	at com.mongodb.internal.connection.InternalStreamConnection$MessageHeaderCallback$MessageCallback.onResult(InternalStreamConnection.java:812)Caused by: org.bson.BsonInvalidOperationException: readInt64 can only be called when CurrentBSONType is INT64, not when CurrentBSONType is INT32.
      	at com.mongodb.internal.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:671)	at com.mongodb.internal.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:668)	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:252)	at com.mongodb.internal.connection.AsynchronousChannelStream$BasicCompletionHandler.completed(AsynchronousChannelStream.java:235)	at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)	at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:282)	at java.base/sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ReadTask.completed(WindowsAsynchronousSocketChannelImpl.java:581)	at java.base/sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:387)	at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)	at java.base/java.lang.Thread.run(Thread.java:829) 

      My understanding of this exception is that the BSON library is assuming that all short numbers must map to Int objects, and this assumption doesn't match the Long type it's being asked to deserialize the value to.

      I've searched both this Jira and the Internet in general, and I have been able to find pretty much no information, but this does seem like a bug and a breakage of expected behaviour.

       

            Assignee:
            slav.babanin@mongodb.com Slav Babanin
            Reporter:
            gdude2002@gmail.com Gareth Coles
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: