[JAVA-700] Cannot Serialize/Deserialize ObjectId using Adobe BlazeDS(flex-messaging) Created: 22/Nov/12  Updated: 25/Jun/13  Resolved: 25/Nov/12

Status: Closed
Project: Java Driver
Component/s: API, Codecs
Affects Version/s: 2.9.1, 2.9.2, 2.9.3
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Daniel Marcotte Assignee: Unassigned
Resolution: Done Votes: 1
Labels: ObjectId, adobe, blazeds, deserialization, driver, serialization
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows 2008 Server
Java JDK 7u07
MongoDB Driver : mongo-2.9.3.jar
Adobe BlazeDS : flex-messaging-core.jar


Attachments: File object_id_serialization_example.rar    

 Description   

Hello,

I use Native Adobe BlazeDS Library used to serialize and deserialize AMF (Action Message Format) which can convert native ActionScript3/Flex objects to Java Objects. This serialization library looks for "public" non-transient fields in the object, recursively and transform them from AS/Java | Java/As. However, in the ObjectId class, the "_inc", "_time" and "_machine" fields are using default access modifiers and are "final int".

In the ObjectId default constructor a new ID is generated :
/** Create a new object id.
*/
public ObjectId(){
_time = (int) (System.currentTimeMillis() / 1000);
_machine = _genmachine;
_inc = _nextInc.getAndIncrement();
_new = true;
}

Doing so, BlazeDS creates a new ObjectId on deserialization and cannot modifier furthermore the "final int". The ObjectId is a new one.

**********************************************************
Serializing ObjectId...
Before serialization : time '10000', machine '20', inc '30', _id '0000000a000000140000001e'
Deserialized ObjectId...
After serialization : time '1353591710000', machine '1079454374', inc '-693442528', _id '50ae2b9e40572aa6d6aae820'
**********************************************************

I've modified your ObjectId class and rebuilt it with "public int _inc" instead of "final int _inc" and it now works properly. However, I understand that it breaks your class encapsulation.

**********************************************************
Serializing ObjectId...
Before serialization : time '10000', machine '20', inc '30', _id '0000000a000000140000001e'
Deserialized ObjectId...
After serialization : time '10000', machine '20', inc '30', _id '0000000a000000140000001e'
**********************************************************

I would like to know if you plan on something regarding this class. Would it be possible to :

1 - make fields public instead of package-protected final?
2 - would it be possible to leave the constructor empty and add a new ".newId()" method?
3 - Is it a good idea to create a ObjectId2 class that encapsulates an ObjectId and a public String so that the library BlazeDS can properly serialize/deserialize the String and create the ObjectId using the String? What would be the impact in the database PrimaryKey?
4 - Do you have any better idea?

I've attached a demo with the native library and the modified one.

Thanks for your time.

Daniel Marcotte



 Comments   
Comment by Jeffrey Yemin [ 23/Nov/12 ]

Hi Daniel,

I definitely want to leave the ObjectId class immutable, which means that all fields are final and need to be initialized in every constructor. This insures that ObjectId instances are thread-safe and don't require any further synchronization.

I think your best bet is to something like option 3 in the description. Just make sure that you don't try to insert instances of ObjectId2 into Mongo. You'll have to convert to ObjectId before insertion.

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