Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Avoid conflicts due to spl_object_hash.#5689

Closed
mathieudz wants to merge 3 commits into
doctrine:masterfrom
mathieudz:pr-oid
Closed

Avoid conflicts due to spl_object_hash.#5689
mathieudz wants to merge 3 commits into
doctrine:masterfrom
mathieudz:pr-oid

Conversation

@mathieudz
Copy link
Copy Markdown
Contributor

When merging an entity with a to-many association, it will store the
original entity data using the object hash of the to-be-merged entity
instead of the managed entity. Since this to-be-merged entity is not
managed by Doctrine, it can disappear from the memory. A new object
can reuse the same memory location and thus have the same object hash.
When one tries to persist this object as new, Doctrine will refuse it
because it thinks that the entity is managed+dirty.

This patch is a very naive fix: it just disables storing the original
entity data in case of to-many associations. It may not be the ideal
or even a good solution at all, but it solves the problem of object
hash reuse.

The test case relies on the immediate reusing of memory locations by
PHP. The variable $user has twice the same object hash, though referring
a different object. Tested on PHP 5.6.17

Without the fix, the test fails on the last line with:
A managed+dirty entity Doctrine\Tests\Models\CMS\CmsUser@[...] can not
be scheduled for insertion.

When merging an entity with a to-many association, it will store the
original entity data using the object hash of the to-be-merged entity
instead of the managed entity. Since this to-be-merged entity is not
managed by Doctrine, it can disappear from the memory. A new object
can reuse the same memory location and thus have the same object hash.
When one tries to persist this object as new, Doctrine will refuse it
because it thinks that the entity is managed+dirty.

This patch is a very naive fix: it just disables storing the original
entity data in case of to-many associations. It may not be the ideal
or even a good solution at all, but it solves the problem of object
hash reuse.

The test case relies on the immediate reusing of memory locations by
PHP. The variable $user has twice the same object hash, though referring
a different object. Tested on PHP 5.6.17

Without the fix, the test fails on the last line with:
A managed+dirty entity Doctrine\Tests\Models\CMS\CmsUser@[...] can not
be scheduled for insertion.
@mathieudz
Copy link
Copy Markdown
Contributor Author

In the meanwhile I noticed that #1465 is created for the same issue.
I think that this PR is more simple and correct. I don't see why Doctrine would need to keep original entity data when merging. Furthermore, only to-many relations are stored.

@Ocramius
Copy link
Copy Markdown
Member

Ocramius commented Mar 1, 2016

I don't see why Doctrine would need to keep original entity data when merging

Seems like an uncovered scenario indeed...

$user = new CmsUser();
$this->_em->merge($user);

$user = null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add an assertion that verifies that the spl object hash of $user is NOT in the UnitOfWork at this point in time?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right after the null assignment? How do you define "being in the UnitOfWork"?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right after the null assignment, yes. Checking these properties should be sufficient, I suppose.

@Ocramius Ocramius added the Bug label Mar 1, 2016
@Ocramius Ocramius added this to the 2.5.5 milestone Mar 1, 2016
parent::setUp();
}

public function testOidReuse()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for whoever gets to merge this: we need to first move the test to the UnitOfWorkTest

@Ocramius Ocramius self-assigned this Sep 10, 2016
Ocramius added a commit that referenced this pull request Sep 10, 2016
Ocramius added a commit that referenced this pull request Sep 10, 2016
Ocramius added a commit that referenced this pull request Sep 10, 2016
Ocramius added a commit that referenced this pull request Sep 10, 2016
Ocramius added a commit that referenced this pull request Sep 10, 2016
@Ocramius Ocramius closed this in 2210505 Sep 10, 2016
@Ocramius
Copy link
Copy Markdown
Member

Merged, thanks @mathieudz!

master: 2210505
2.5: b7bfbb6

alexgurrola pushed a commit to Sitetheory-Archive/doctrine2 that referenced this pull request Apr 13, 2017
alexgurrola pushed a commit to Sitetheory-Archive/doctrine2 that referenced this pull request Apr 13, 2017
alexgurrola pushed a commit to Sitetheory-Archive/doctrine2 that referenced this pull request Apr 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants