mongodb-odm
mongodb-odm copied to clipboard
Change detection doesn't work with objects and custom types
I've got a property $foo
on my document that holds a mutable object. That object is converted to an array by a custom type when persisting the document. Unfortunately, when I change a property on that mutable object, $foo
isn't recognized as having changed because of this condition:
if ($orgValue === $actualValue) {
// ...
continue;
// ...
}
It's still the same instance, and so the contition evaluates to true
.
Is there a better way to detect changes? Maybe something like comparing two spl_object_hash()
es?
spl_object_hash()
gave us enough headache with embedded documents since they can be reused, I'm not sure I would like to follow that way... As a temporary solution I'd recommend using immutable objects while we try to figure out a way to fix the bug.
Thanks, I already changed it to be immutable.
Just to update, so far I have no idea how this could be introduced in a bugfix manner...
Offhand I recalled there was #976 (but that'd be feature) and also I have an idea for 2.0 that could fix the issue at hand, namely I'm pondering over using database values for preparing change sets.
Hi!, happy 1 year anniversary for this issue. This particular issue has long vexed me in one of my projects. We use value objects extensively and in our world a value object with the same values should evaluate to be equal to a different value object with the same values.
I think ODM should make use of an interface offered in Common that mimics an interface never accepted into PHP core: https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Comparable.php
This code block could check if $orgValue implements Comparable, if so, use the compareTo($other) method. If not, default to === check.
This is actually interesting, I had no idea such interface exists :) Given our current plans for 2.0 it indeed might be feasible to add as a feature earlier. @alcaeus @jmikola any downsides coming to your mind? From my perspective it can get into our way later if we'd like to remove the Comparable
approach.
The Comparable interface looks like a good option here. I recall @guilhermeblanco trying to get this into core some time ago, but I wasn't aware it was added to Doctrine Common. Let's confirm if ORM is using it to address the same use case here.
/cc @beberlei
@jmikola you need to work on your summoning abilities a bit ;)
Using the comparable interface would make sense - we could compare the objects using ===
if one of them doesn't implement Comparable
and use that if both of them do. I'm moving this to the 2.0 milestone since I don't think I'll get to it before 1.2, which I'm trying to wrap up asap.
The issue has been reported almost 4 years ago. A good solution (using the Comparable
interface) has been proposed three years ago. The problem has still not been solved? Is this really true or am I missing something?
Is there any other solution for this?
The problem has still not been solved?
Indeed it hasn't. If you're up for it, we're happy to assist while you create the pull request.