Summary
Hello,
I’m using :
-> Kotlin driver => org.mongodb:mongodb-driver-kotlin-sync:4.10.2
(the same issue exists in org.mongodb:mongodb-driver-kotlin-coroutine:4.10.1 too)
-> MongoDB Atlas Dedicated Cluster M10 v6.1
I have a data class with a nullable String field
{{data class MyData( val myfield: String?
)}}
When I read the value from the DB, here are what is printed on console :
- if myfield does NOT exist in the DB => it successfully prints “MyData(myfield=null)”
- if myfield exists and contains “myvalue” => it successfully prints “MyData(myfield=myvalue)”
- if myfield exists and contains null value (BSONType is NULL) => I would expect that it prints “MyData(myfield=null)” but it is not!? It throws the BsonInvalidOperationException “readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is NULL.”
Could you please tell me what’s wrong? Thanks!
How to Reproduce
Here is a very simple code to reproduce (replace XXX, YYY, ZZZ with your values)
data class MyData( val myfield: String? ) fun main(args: Array<String>) { val uri = "XXXXXXXXX" val databaseName = "YYYYYYYY" val collectionName = "ZZZZZZZ" val mongoClient = MongoClient.create(uri) val db = mongoClient.getDatabase(databaseName) val collection = db.getCollection<MyData>(collectionName) val doc = collection.find().firstOrNull() if (doc != null) { println(doc) } else { println("No matching documents found.") } mongoClient.close() }
Additional Background
Here is the exception trace
Exception in thread "main" org.bson.codecs.configuration.CodecConfigurationException: Unable to decode myfield for MyData data class. at org.bson.codecs.kotlin.DataClassCodec.decode(DataClassCodec.kt:92) at com.mongodb.internal.operation.CommandResultArrayCodec.decode(CommandResultArrayCodec.java:52) at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:60) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:87) at org.bson.codecs.BsonDocumentCodec.decode(BsonDocumentCodec.java:42) at org.bson.internal.LazyCodec.decode(LazyCodec.java:53) at org.bson.codecs.BsonDocumentCodec.readValue(BsonDocumentCodec.java:104) at com.mongodb.internal.operation.CommandResultDocumentCodec.readValue(CommandResultDocumentCodec.java:63) 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:565) at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:455) at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:370) at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:114) at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:719) at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:76) at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:203) at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:115) at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:83) at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:74) at com.mongodb.internal.connection.DefaultServer$OperationCountTrackingConnection.command(DefaultServer.java:287) at com.mongodb.internal.operation.CommandOperationHelper.createReadCommandAndExecute(CommandOperationHelper.java:245) at com.mongodb.internal.operation.FindOperation.lambda$execute$1(FindOperation.java:324) at com.mongodb.internal.operation.OperationHelper.lambda$withSourceAndConnection$0(OperationHelper.java:345) at com.mongodb.internal.operation.OperationHelper.withSuppliedResource(OperationHelper.java:370) at com.mongodb.internal.operation.OperationHelper.lambda$withSourceAndConnection$1(OperationHelper.java:344) at com.mongodb.internal.operation.OperationHelper.withSuppliedResource(OperationHelper.java:370) at com.mongodb.internal.operation.OperationHelper.withSourceAndConnection(OperationHelper.java:343) at com.mongodb.internal.operation.FindOperation.lambda$execute$2(FindOperation.java:321) at com.mongodb.internal.operation.CommandOperationHelper.lambda$decorateReadWithRetries$3(CommandOperationHelper.java:192) at com.mongodb.internal.async.function.RetryingSyncSupplier.get(RetryingSyncSupplier.java:67) at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:332) at com.mongodb.internal.operation.FindOperation.execute(FindOperation.java:72) at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:153) at com.mongodb.client.internal.FindIterableImpl.first(FindIterableImpl.java:213) at com.mongodb.kotlin.client.MongoIterable.firstOrNull(MongoIterable.kt:38) at MainKt.main(Main.kt:20)Caused by: org.bson.BsonInvalidOperationException: readString can only be called when CurrentBSONType is STRING, not when CurrentBSONType is NULL. at org.bson.AbstractBsonReader.verifyBSONType(AbstractBsonReader.java:689) at org.bson.AbstractBsonReader.checkPreconditions(AbstractBsonReader.java:721) at org.bson.AbstractBsonReader.readString(AbstractBsonReader.java:456) at org.bson.codecs.StringCodec.decode(StringCodec.java:80) at org.bson.codecs.StringCodec.decode(StringCodec.java:31) at org.bson.codecs.DecoderContext.decodeWithChildContext(DecoderContext.java:96) at org.bson.codecs.kotlin.DataClassCodec.decode(DataClassCodec.kt:90) ... 37 more
Here is my build.gradle.kts
plugins { kotlin("jvm") version "1.9.10" application } group = "org.example" version = "1.0-SNAPSHOT" repositories { mavenCentral() } dependencies { testImplementation(kotlin("test")) implementation("org.mongodb:mongodb-driver-kotlin-sync:4.10.2") //implementation("org.mongodb:mongodb-driver-kotlin-coroutine:4.10.1") } tasks.test { useJUnitPlatform() } kotlin { jvmToolchain(8) } application { mainClass.set("MainKt") }
Thanks for your help!