Java, Mongo, Ruby, & UUIDs. A “fun” afternoon.

Recently I had cause to dig a little further than I’d have liked to into the world of UUID representation in MongoDB. It wasn’t the most trivial thing in the world, and I couldn’t find resources specific to the problem I had, so I thought I’d put something up on the off-chance it aids someone else in the future. A gained a lot of info from reading Studio 3t’s article on UUIDs in Mongo, and it’s worth checking out if you’re having issues too.

We have a Java backend, which writes UUIDs into Mongo using the 0x03 “UUID (old)” subtype. I had cause to write a quick script to push some data into Mongo and jumped to Ruby, being my scripting language of choice. I got quite deep on all other functions of this script and it was almost complete before I realised something was very amiss.

I would give this script a UUID that our application knows about, e.g. “016df4ad-9f63-4b28-b85a-be6f5046981f”. That would build some data and throw it into Mongo using: BSON::Binary.new '016df4ad-9f63-4b28-b85a-be6f5046981f', :uuid_old Here’s how that looked in Mongo vs. what I expected:
expected: BinData(3,"KEtjn630bQEfmEZQb75auA==")
actual: BinData(3,"MDE2ZGY0YWQtOWY2My00YjI4LWI4NWEtYmU2ZjUwNDY5ODFm")

Uh oh. I confirmed a similar issue using just “:uuid” as the sub-type, and entered the rabbit-hole. It seems the 0x03 sub-type was interpreted differently by different language drivers, and they aren’t interoperable as a result. The “correct” solution is to use 0x04, which is designed to be compatible across drivers and languages. That’s a nice ticket for the tech-debt backlog, but I didn’t have time for it now.

Luckily, the C# driver recognised the issues with interoperability and included some utilities to convert Mongo’s data into readable UUIDs as different languages would see them. These utilities were in Javascript but were fairly easy to port to Ruby, so I thought I would share it. Hopefully, it will help someone else in the future!


Comments ( 0 )

    Leave A Comment

    Your email address will not be published. Required fields are marked *