When create two objects referring to each other at the same time, why the first's ObjectId is changed after stored into MongoDB?

StackOverflow https://stackoverflow.com/questions/8291719

Question

I am using spring roo, but I think this is not a spring roo issue but the MongoDB issue.

I have two classes (documents) referring to each other.

public class Dummy {
    private String dummyString;

    @DBRef
    private Dummy2 dummy2;
}

public class Dummy2 {
    private String dummyString;
    private ObjectId dummyId;
}

'Dummy' refers to 'Dummy2' by reference.
'Dummy2' refers to 'Dummy' by storing ObjectId manually due to technical reasons.

Here is my integration test creating two objects.

@Test
public void testDummyWithDummy2() {
    DummyDataOnDemand dod = new DummyDataOnDemand();
    Dummy dummy = dod.getNewTransientDummy(0);
    dummyService.saveDummy(dummy);

    Dummy2DataOnDemand dod2 = new Dummy2DataOnDemand();
    Dummy2 dummy2 = dod2.getNewTransientDummy2(0);
    dummy2.setDummyId(dummy.getId());
    dummy2Service.saveDummy2(dummy2);

    dummy.setDummy2(dummy2);
    dummyService.updateDummy(dummy);
}

I found that the results are inconsistencies.
There are two situations so far.

  1. It works correctly. They refer to each other as expected.

    Dummy:

    {
        "_id": ObjectId("4ecfa5429418d09a94f1c8ae"),
        "_class": "com.mytest.model.Dummy",
        "dummyString": "dummyString_0",
        "dummy2": {
            "$ref": "dummy2",
            "$id": ObjectId("4ecfa5429418d09a94f1c8af") 
        } 
    }
    


    Dummy2:

    {
        "_id": ObjectId("4ecfa5429418d09a94f1c8af"),
        "_class": "com.mytest.model.Dummy2",
        "dummyString": "dummyString_0",
        "dummyId": ObjectId("4ecfa5429418d09a94f1c8ae") 
    }
    
  2. Sometimes, dummy refers to nothing and dummy2 refers to invalid ObjectId.

    Dummy:

    {
        "_id": ObjectId("4ecfa039941836a18fe88b24"),
        "_class": "com.mytest.model.Dummy",
        "dummyString": "dummyString_2147483647" 
    }
    


    Dummy2:

    {
        "_id": ObjectId("4ecfa039941836a18fe88b23"),
        "_class": "com.mytest.model.Dummy2",
        "dummyString": "dummyString_0",
        "dummyId": ObjectId("4ecfa039941836a18fe88b22") 
    }
    

I wonder why the latter result could be happened. It seems that the Dummy is not the same that Dummy2 is referring to, look like the newly created one. But where is the Dummy with ObjectId("4ecfa039941836a18fe88b22")? Is it lost? Why?

Roo: 1.2.0.M1 [rev 1fa252f]
MongoDB: 2.0.1

Was it helpful?

Solution 2

After done more tests and consulted the MongoDB log. I found that because the Spring Roo's generated integration tests include some tests that get a random document to process. That's why the results of my integration test are inconsistency.

So I would separate my own tests from the Roo's generated tests to preserve the expected results on MongoDB.

OTHER TIPS

how did you notice the bad objects? Was it by querying the collection afterwards? Also, how did you insert the objects, did you do a large bulk operation?

It is important to understand that by default the writes with mongodb are not acknowledged. There can be an error (dup key, or just socket buffering) and you application will not get an exception or get a delayed one. Make sure you use SAFE writes (using WriteConcern) then do you test again and watch for any exception.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top