Mongodb-odm: Saving document with bi-directional reference leads to deletion of references of other documents

Created on 9 Apr 2018  路  6Comments  路  Source: doctrine/mongodb-odm

I'm currently working on a test case for this and will add a detailed explanation once this is done and I managed to wrap my mind around this.

Bug

Most helpful comment

Maybe it's quicker to explain this in a short call (and our native language). I'll send my mobile phone number to you via email. Feel free to call.

Thanks - it wasn't necessary after all: I was able to step-debug through your test case and immediately see the problem. I'm looking at a fix and will try to get it done soon - your suggestion to fix in #1781 is not entirely correct as it causes an additional database load for every proxy being initialized, which is a big performance problem.

Again, thank you for the excellent work in debugging the issue and producing a test case! 馃憤

All 6 comments

Please do - I also suggest checking any orphanRemoval settings on the references.

I finally figured out what's going on here.

Note: I've modelled the test case after the application in which I noticed this bug. Maybe the test case can be simplified even more (get rid of MetaDocument class and add public properties to class GH1775Post itself).

The test case does this:

  • Create _Blog_
  • Create _Image_
  • Create _Post1_ which refers to _Blog_ and _Image_
  • Add reference to _Post1_ to _Blog_
  • Create _Post2_ which refers to _Blog_ and _Image_
  • Add reference to _Post2_ to _Blog_
    The reference from _Post1_ to _Image_ is now gone!

What happens internaly
Due to some properties being public (via parent class) hydration of _Post1_ triggers a second load and a second hydration of _Post1_. Because other properties are protected, these properties will be hydrated before the second hydration is triggered which will lead to different objects being in use for _$orgValue === $actualValue_ comparison (for _Post1::$images_) in _UnitOfWork::computeOrRecomputeChangeSet_. Because _PersistentCollection::$mongoData_ is ignored for calculation of the changeset, _Post1::$images_ is emptied.

All this can be worked around by using protected properties everywhere, but IMHO this issue should be fixed nonetheless (or mongodb-odm should refuse to work with public properties at all).

My brain and eyes hurt after endless hours of debugging. I hope the above still makes sense.

My brain and eyes hurt after endless hours of debugging.

My brain hurts from reading this - I'll have to take some time to think this through, ideally in the morning. In the meantime, thanks for your time and efforts to debug this and produce a test case!

@alcaeus Maybe it's quicker to explain this in a short call (and our native language). I'll send my mobile phone number to you via email. Feel free to call.

Maybe it's quicker to explain this in a short call (and our native language). I'll send my mobile phone number to you via email. Feel free to call.

Thanks - it wasn't necessary after all: I was able to step-debug through your test case and immediately see the problem. I'm looking at a fix and will try to get it done soon - your suggestion to fix in #1781 is not entirely correct as it causes an additional database load for every proxy being initialized, which is a big performance problem.

Again, thank you for the excellent work in debugging the issue and producing a test case! 馃憤

PR fixing the bug was merged, closing

Was this page helpful?
0 / 5 - 0 ratings