Avoid conflicts due to spl_object_hash().
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.
This commit is contained in:
parent
5365a418e9
commit
95dcf51ad5
@ -3423,7 +3423,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$managedCol->setOwner($managedCopy, $assoc2);
|
||||
$prop->setValue($managedCopy, $managedCol);
|
||||
|
||||
$this->originalEntityData[spl_object_hash($entity)][$name] = $managedCol;
|
||||
// $this->originalEntityData[spl_object_hash($entity)][$name] = $managedCol;
|
||||
}
|
||||
|
||||
if ($assoc2['isCascadeMerge']) {
|
||||
|
34
tests/Doctrine/Tests/ORM/Functional/OidReuseTest.php
Normal file
34
tests/Doctrine/Tests/ORM/Functional/OidReuseTest.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
|
||||
use Doctrine\Tests\Models\CMS\CmsUser;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class OidReuseTest extends OrmFunctionalTestCase
|
||||
{
|
||||
|
||||
private $userId;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->useModelSet('cms');
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testOidReuse()
|
||||
{
|
||||
$user = new CmsUser();
|
||||
$this->_em->merge($user);
|
||||
|
||||
$user = null;
|
||||
|
||||
$user = new CmsUser();
|
||||
$this->_em->persist($user);
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user