-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DDC-2785] Add failing test #843
Conversation
Hello, thank you for creating this pull request. I have automatically opened an issue http://www.doctrine-project.org/jira/browse/DDC-2786 We use Jira to track the state of pull requests and the versions they got |
$phone = new CmsPhonenumber(); | ||
$phone->phonenumber = "1234"; | ||
$hash = spl_object_hash($phone); | ||
$this->_em->persist($phone); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test is wrong becaues of this line, when calling ->persist() the entity is managed, not NEW. You can move this line into the if condition below and then it passes green.
Hash collisions are ok, Doctrine fixes them by cleaning the internals of the UoW up.
See my code comment for why this is wrong. Can you explain a little bit what prompted you to create this PR and the issue? |
@beberlei You're right about the test being wrong, I looked at the code in UoW again, and this can't return STATE_NEW. The problem I was trying to reproduce is that I've encountered situations where I instantiated a new object and EM would tell my that it is already managed when calling In one case, a new object instance which is created in a But in the other case, it's just a new object instance passed to Doctrine via I've played around with the unit test a while, but I can't get it to behave the same way as my code, and even there, it only when happens when I run a pretty large test suite (of a depending project) against it. So there is some difference, but I don't know what it could be. But the workarounds linked above fix the problem, and at least in the first case, I can't see how it could be an error in my code (but I've been known to be wrong before :-) |
@beberlei: I think I finally figured out how to reproduce the problem: The trick was to get a reference on the object. This somehow provokes the situation described above. But of course, I might still be missing something, so if you could look over the test and tell me if the sequence of calls I'm using is supposed to work the way I expect them to, it would be most helpful! |
ping I don't mean to stress, but it would really be helpful if someone could comment on this. I've been chasing sporadic failures in my Doctrine code for a long while now, and AFAICT they usually derive from some variation of the code above. |
|
||
use Doctrine\Tests\Models\CMS\CmsPhonenumber; | ||
|
||
require_once __DIR__ . '/../../../TestInit.php'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed anymore
I've fixed the CS problems mentioned by @Ocramius now. Let me know if you need more information or if I can help with debugging somehow |
P.S.: I don't think that the $x = $this->_em->getReference(get_class($phone), $phone->phonenumber); then the test passes |
@stof I removed |
Just to let you know: I was trying to run the test again against current master, hoping that maybe this was fixed by #5689, but the test still fails, i.e. there still seems to be a way for hash collisions to occur |
Your test is using In your test, you first execute $x = $this->_em->getReference(get_class($phone), $phone->phonenumber); The This leads to an internal inconsistency in the UoW, since the #10785 would have spotted this; it rejects your So my take would be that the test shows why it would be good to have the #10785 check, but it does not demonstrate a problem with object id collistions in a valid way. |
@mpdude AFAIR the situation I had in my real code was that I loaded some stuff with querybuilder, and associations for the loaded entites got automatically initialised as references. Then, when later loading those entities the object hash collisions cropped up (there may have been some |
The reason why this has staid open for so long is precisely because the reproducer was not deterministic. As much as I appreciate the effort put into trying to hunt the bug, we need precise pinpointing to avoid future regressions and other related bugs: once things get thrown over the fence, we can't really have something that fails randomly, or for certain contributors only. @mpdude if you think your approach will uncover the bug with precision, do feel free to send a patch. @flack I'm still reading here, btw, it's just not my job to do so :D |
As for current state: this still targets travis-ci, so I guess it's very (very!) outdated anyway. Your call, @flack: even if you decide to close here, it is still a breadcrumb for anyone picking this up in future. Meanwhile, Jira has been shut down many years ago, so initial context is lost. |
@Ocramius DDC-2785 also got migrated to github back then: #3533, so original context can still be viewed if it's interesting to anyone. I'll keep the PR open for now, maybe I'll take another stab at a different approach (at some point in the future), but I'm not sure this can even be fully deterministically reproduced. I mean, the hashes are more or less randomly generated by PHP internally, so whether or not you get a collision will always involve some chance, no? All I know is that the collisions still happen in real life, I have some logging for it in my code and just checked a smallish server (only a handful of daily active users) and I get around 5 collisions every day. |
Identifiers are deterministic, AFAIK: what we're missing is something like a GC causing an identifier reuse, perhaps. Anyway, I also don't have better answers, at this stage. |
I think #3037 is the main issue dealing with these spurious hash collisions, and yes, it's still lacking a reproducer. What I wanted to say is that I believe this code here is not a valid reproducer, since it uses the ORM in a wrong manner (see comment). #10785 is a WIP adding a check that would call this out. |
The right way to fix this would be to use weak maps, wouldn't it? |
Regarding the code in this PR, I think it’s a user error to first ask the EM for a reference for given ID and then pass another object to Weak maps might help simplify state management in the UoW, but this code here needs to be fixed on the user side. |
As one takeaway from doctrine#3037 (comment) and doctrine#843, we should look into better explaining the `EntityManager::getReference()` method, it’s semantics, caveats and potential responsibilities placed on the user. This PR tries to do that, so it fixes doctrine#10797.
* Explain `EntityManager::getReference()` peculiarities As one takeaway from #3037 (comment) and #843, we should look into better explaining the `EntityManager::getReference()` method, it’s semantics, caveats and potential responsibilities placed on the user. This PR tries to do that, so it fixes #10797. * Update docs/en/reference/advanced-configuration.rst Co-authored-by: Grégoire Paris <[email protected]> --------- Co-authored-by: Grégoire Paris <[email protected]>
Add a failing test for
http://www.doctrine-project.org/jira/browse/DDC-2785