doctrine/mongodb-odm — pull request #878 by danez (2014-05-15 09:08:10+00:00)
Title: spl_object_hash collision when doing merge() twice

After spending hours of trying to figure out why our system does not save certain documents, and afterwards hours of producing a reproducable testcase, I finally managed to track it down to the merge inside odm.

##### Background:
We have a **main-document** that embedds on **embedded-document**.
We also have a **other-document** with just an identifier.
Initially in the test we get the **main-document** from somewhere other than doctrine (cache for example).

##### Problem:
Now when calling merge on the detached **main-document**, the logic inside the *UnitOfWork::doMerge* creates a new **embedded-document** and merges it with the detached one.
When calling merge a second time on the same detached **main-document**, its "managed version" is already found in the identity map. Still a new **embedded-document** is created and merged with the one from the detached **embedded-document**. After the **embedded-document** is merged it is set back on the **main-document**, replacing the previous managed **embedded-document**. This previous document in our scenario now does not have any references (because documents without identifiers are not in the identity map) and is probably gc by php.
The newly created **other-document** that the test tries to insert afterwards is then detected as manged, as the spl_object_hash for this document is the same as for the unreferenced **embedded-document**.

##### Fix:
I already have a fix for that in the second commit, but I'm not sure if it introduces any side effects that I might not be aware of. But I can not see anything bad currently and all the tests still work.

The fix simply detaches the (at least inside odm) not anymore referenced embedded document.

Relates to #642