-
Type: Bug
-
Resolution: Duplicate
-
Priority: Critical - P2
-
None
-
Affects Version/s: 2.0.4
-
Component/s: Querying
-
Labels:None
-
Environment:Linux:
Linux 2.6.18-128.1.1.el5 #1 SMP Mon Jan 26 13:58:24 EST 2009 x86_64 x86_64 x86_64 GNU/Linux
OSX (10.6.8):
Darwin 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386 i386 MacPro1,1 Darwin
MongoDB 2.0.4
Mongo Java Driver 2.7.3
Casbah 2.1.5-1
Salat 0.0.8-SNAPSHOTLinux: Linux 2.6.18-128.1.1.el5 #1 SMP Mon Jan 26 13:58:24 EST 2009 x86_64 x86_64 x86_64 GNU/Linux OSX (10.6.8): Darwin 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun 7 16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386 i386 MacPro1,1 Darwin MongoDB 2.0.4 Mongo Java Driver 2.7.3 Casbah 2.1.5-1 Salat 0.0.8-SNAPSHOT
-
ALL
We are developing a straightforward Scala web application with a MongoDB backend using Salat+Casbah. We've noticed that sometimes our updates via Salat+Casbah fail to succeed. I can now explain why it's happening:
- We create documents using Salat which closely correspond to our model (Scala case classes). I can observe that the field ordering of the newly-inserted documents match the model.
- After some update, the fields in the document are updated to be in alphanumeric order (as documented).
- Salat is still able to deserialize the document as a proper object despite the field re-ordering.
- When we try to update the document using code like collection.update(old, new) as a form of optimistic locking – to ensure that the document hasn't been updated under us – this will fail even though the application's representation and the database's representation are isomorphic.
Although we ran into this issue using Salat+Casbah, I was able to reproduce it using the Mongo CLI:
# Insert a document with fields in alphanumeric order: var o = { "_id" : NumberLong(12000009), "createdBy" : NumberLong(1185), "creationDate" : ISODate("2008-02-06T06:00:00Z"), "draftHamsVendor" : { "id" : NumberLong(120), "name" : "Johnny Appleseed", }, "name" : "Johnny Appleseed", "users" : [ NumberLong(1185) ] } db.test.save(o) # Try to find the document using the model's field ordering: var p = { "_id" : NumberLong(12000009), "creationDate" : ISODate("2008-02-06T06:00:00Z"), "createdBy" : NumberLong(1185), "name" : "Johnny Appleseed", "draftHamsVendor" : { "name" : "Johnny Appleseed", "id" : NumberLong(120), }, "users" : [ NumberLong(1185) ] } > db.test.findOne(p) null
For some reason, this issue only surfaces with nested documents, despite claims that key order is significant in queries. For example, the above inserted object will be found by both of the following queries:
db.test.find({"creationDate" : ISODate("2008-02-06T06:00:00Z"), "createdBy" : NumberLong(1185)}) db.test.find({"createdBy" : NumberLong(1185), "creationDate" : ISODate("2008-02-06T06:00:00Z")})
I gather that both the significance of key ordering and the potential field re-ordering of documents are both by design, but the interaction between these two aspects seems to be a bad bug; the application runs fine until MongoDB needs to re-order fields in some documents. This is a subtle and unexpected bug, in part because the significance of key ordering in queries and documents is hardly documented at all.