[JAVA-2318] UUID serialization to JSON causes parsing error. Created: 21/Sep/16  Updated: 11/Sep/19  Resolved: 21/Sep/16

Status: Closed
Project: Java Driver
Component/s: BSON, JSON
Affects Version/s: 3.3.0
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: Sebastian Binder Assignee: Unassigned
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

Hello.
I have a problem with Java UUID serialization. I'm having a UUID object and wanna serialize it:

Java

JSON.serialize(myUuid)

Now when using this snipped in a more complex JSON as the following and parsing it with the code below the json, an error shows up.

json

{  
   "_id":"w1bEDr6",
   "server":"Lobby-01",
   "created":{  
      "$date":"2016-09-21T09:00:19.001Z"
   },
   "messages":[  
      {  
         "sender":{  
            "$uuid":"93ede72e-3ef0-42eb-a37b-62477df6497f"
         },
         "message":"PLAYER_JOIN",
         "type":"EVENT",
         "timestamp":{  
            "$date":"2016-09-21T09:00:19.002Z"
         }
      },
      {  
         "sender":{  
            "$uuid":"93ede72e-3ef0-42eb-a37b-62477df6497f"
         },
         "message":"/chatlog",
         "type":"COMMAND",
         "timestamp":{  
            "$date":"2016-09-21T09:00:23.821Z"
         }
      },
      {  
         "sender":{  
            "$uuid":"93ede72e-3ef0-42eb-a37b-62477df6497f"
         },
         "message":"PLAYER_QUIT",
         "type":"EVENT",
         "timestamp":{  
            "$date":"2016-09-21T09:00:25.643Z"
         }
      }
   ]
}

Java

Document.parse(json)

Error

java.lang.IllegalArgumentException: Invalid BSON field name $uuid
    at org.bson.AbstractBsonWriter.writeName(AbstractBsonWriter.java:494)
    at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:188)
    at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:172)
    at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
    at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:172)
    at org.bson.codecs.DocumentCodec.writeIterable(DocumentCodec.java:197)
    at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:170)
    at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:189)
    at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:131)
    at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
    at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
    at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:101)
    at com.mongodb.connection.InsertCommandMessage.writeTheWrites(InsertCommandMessage.java:43)
    at com.mongodb.connection.BaseWriteCommandMessage.encodeMessageBodyWithMetadata(BaseWriteCommandMessage.java:129)
    at com.mongodb.connection.RequestMessage.encodeWithMetadata(RequestMessage.java:160)
    at com.mongodb.connection.WriteCommandProtocol.sendMessage(WriteCommandProtocol.java:212)
    at com.mongodb.connection.WriteCommandProtocol.execute(WriteCommandProtocol.java:101)
    at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:67)
    at com.mongodb.connection.InsertCommandProtocol.execute(InsertCommandProtocol.java:37)
    at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:159)
    at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:286)
    at com.mongodb.connection.DefaultServerConnection.insertCommand(DefaultServerConnection.java:115)
    at com.mongodb.operation.MixedBulkWriteOperation$Run$2.executeWriteCommandProtocol(MixedBulkWriteOperation.java:455)
    at com.mongodb.operation.MixedBulkWriteOperation$Run$RunExecutor.execute(MixedBulkWriteOperation.java:646)
    at com.mongodb.operation.MixedBulkWriteOperation$Run.execute(MixedBulkWriteOperation.java:401)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:179)
    at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)
at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:168)                                                                       [14/9133]
    at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:230)
    at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:221)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:168)
    at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:74)
    at com.mongodb.Mongo.execute(Mongo.java:781)
    at com.mongodb.Mongo$2.execute(Mongo.java:764)
    at com.mongodb.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:515)
    at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:306)
    at com.mongodb.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:297)
<rest of stacktrace removed>

Any idea what's going on here? Is this a bug or an error with my code?



 Comments   
Comment by Jeffrey Yemin [ 21/Sep/16 ]

The com.mongodb.util.JSON serializer does not produce JSON that is compatible with Document.parse. It uses an older JSON format that preceded the MongoDB Extended JSON specification, and we can't really change that older format without breaking existing users.

You have a couple of options. If you don't mind changing JSON formats, stick to Document methods for both encoding to and decoding from JSON:

        UUID myUuid = UUID.randomUUID();
        Document document = new Document("_id", myUuid);
        String strictJSON = document.toJson();                                      // Use Document.toJson() to encode
        System.out.println(strictJSON);
        Document documentParsed = Document.parse(strictJSON);     // Use Document.parse() to decode
        System.out.println(document.equals(documentParsed));

Alternatively, stick to the JSON class for both encoding and decoding:

        UUID myUuid = UUID.randomUUID();
        DBObject dbObject = new BasicDBObject("_id", myUuid);
        String legacyJSON = JSON.serialize(dbObject);                                  // Use JSON.serialize() to encode
        System.out.println(legacyJSON);
        DBObject legacyParsed = (DBObject) JSON.parse(legacyJSON);     // Use JSON.parse to decode
        System.out.println(dbObject.equals(legacyParsed));

Generated at Thu Feb 08 08:56:54 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.