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.