How to store a UUID with binary subtype 0x04 using the MongoDB Java Driver

I am trying to insert an Extended JSON document into a MongoDB collection. This document contains a standard UUID . My problem is that after inserting, the UUID is saved in the legacy LUUID format.

The following (Kotlin) program illustrates my problem:

import com.mongodb.MongoClientSettings
import com.mongodb.MongoCredential
import com.mongodb.ServerAddress
import com.mongodb.client.MongoClients
import com.mongodb.client.MongoCollection
import com.mongodb.connection.ClusterSettings
import org.bson.Document
import org.bson.UuidRepresentation
import org.bson.codecs.DocumentCodec
import org.bson.codecs.UuidCodec
import org.bson.codecs.configuration.CodecRegistries

fun connect(): MongoCollection<Document> =
    MongoClients.create(
        MongoClientSettings.builder()
            .credential(MongoCredential.createCredential("mongo", "admin", "mongo".toCharArray()))
            .applyToClusterSettings { builder: ClusterSettings.Builder ->
                builder.hosts(listOf(ServerAddress("localhost", 27017)))
            }
            .uuidRepresentation(UuidRepresentation.STANDARD)
            .build())
        .getDatabase("uuid-demo")
        .getCollection("collection")

fun parseDocument(json: String): Document =
    Document.parse(
        json,
        DocumentCodec(
            CodecRegistries.fromRegistries(
                CodecRegistries.fromCodecs(UuidCodec(UuidRepresentation.STANDARD)),
                MongoClientSettings.getDefaultCodecRegistry()
            )
        )
    )

fun main(args: Array<String>) {
    val document = parseDocument(
        """
        {
            "someId" : UUID("cfbca728-4e39-4613-96bc-f920b5c37e16")
        }        
        """.trimIndent()
    )
    val collection = connect()

    collection.drop()
    collection.insertOne(document)
    val inserted = collection.find().first()!!

    println(inserted.toJson())
}

However the UUID is stored using the LUUID type with binary subtype 0x03:
{"_id": {"$oid": "5fdb73cc7dab4766e448f2be"}, "someId": {"$binary": {"base64": "z7ynKE45RhOWvPkgtcN+Fg==", "subType": "03"}}}

What I am doing wrong here?

It’s being inserted correctly, as you can see in the shell:

MongoDB Enterprise > db.collection.find()
{ "_id" : ObjectId("5fdc1d15944a7e6e66a2a541"), "someId" : UUID("cfbca728-4e39-4613-96bc-f920b5c37e16") }

The problem is that you need to use the correct codec in your call to Document.toJson. Try this (simplified) program:

fun main(args: Array<String>) {
    val collection = connect()

    val document = Document.parse("""
        {
            "someId" : UUID("cfbca728-4e39-4613-96bc-f920b5c37e16")
        }""",
            collection.codecRegistry.get(Document::class.java)
    )

    collection.drop()
    collection.insertOne(document)
    val inserted = collection.find().first()!!

    println(inserted.toJson(collection.codecRegistry.get(Document::class.java)))
}

which prints:

{
  "_id": {"$oid": "5fdc1d15944a7e6e66a2a541"}, 
  "someId": {"$binary": {"base64": "z7ynKE45RhOWvPkgtcN+Fg==", "subType": "04"}}}

The trick is to use the Codec<Document> from the collection, which has been configured from the UuidRepresentation from the settings.

Hope this helps.

Regards,
Jeff

Hi,

Thank you very much for your help. Unfortunately, it doesn’t quite work. It is still outputting "subType": "03".

I also don’t think that it is inserted correctly. When I query the shell I get:

> db.collection.find()
{ "_id" : ObjectId("5fdc8235119b8e3f3fd06c72"), "someId" : BinData(3,"z7ynKE45RhOWvPkgtcN+Fg==") }

Even

println(
    Document.parse(
        """{"someId" : UUID("cfbca728-4e39-4613-96bc-f920b5c37e16")}""".trimIndent(),
        collection.codecRegistry.get(Document::class.java)
    ).toJson(collection.codecRegistry.get(Document::class.java))
)

"subType": "03".

MongoDB server version: 4.4.2
MongoDB shell version v4.2.0
MongoDB Java driver version: 4.0.5

Ok. It works after I upgraded the version of the driver to 4.1.1. Thanks for your help.

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.