[2.0][DDC-136] Some fixes to internal UnitOfWork logic.
This commit is contained in:
parent
57a97eba01
commit
ab0c7b11c8
@ -771,7 +771,14 @@ class UnitOfWork implements PropertyChangedListener
|
||||
foreach ($this->_entityDeletions as $oid => $entity) {
|
||||
if (get_class($entity) == $className) {
|
||||
$persister->delete($entity);
|
||||
unset($this->_entityDeletions[$oid]);
|
||||
unset(
|
||||
$this->_entityDeletions[$oid],
|
||||
$this->_entityIdentifiers[$oid],
|
||||
$this->_originalEntityData[$oid]
|
||||
);
|
||||
// Entity with this $oid after deletion treated as NEW, even if the $oid
|
||||
// is obtained by a new entity because the old one went out of scope.
|
||||
$this->_entityStates[$oid] = self::STATE_NEW;
|
||||
|
||||
if ($hasLifecycleCallbacks) {
|
||||
$class->invokeLifecycleCallbacks(Events::postRemove, $entity);
|
||||
@ -919,17 +926,21 @@ class UnitOfWork implements PropertyChangedListener
|
||||
public function scheduleForDelete($entity)
|
||||
{
|
||||
$oid = spl_object_hash($entity);
|
||||
if ( ! $this->isInIdentityMap($entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->removeFromIdentityMap($entity);
|
||||
|
||||
if (isset($this->_entityInsertions[$oid])) {
|
||||
if ($this->isInIdentityMap($entity)) {
|
||||
$this->removeFromIdentityMap($entity);
|
||||
}
|
||||
unset($this->_entityInsertions[$oid]);
|
||||
return; // entity has not been persisted yet, so nothing more to do.
|
||||
}
|
||||
|
||||
if ( ! $this->isInIdentityMap($entity)) {
|
||||
return; // ignore
|
||||
}
|
||||
|
||||
$this->removeFromIdentityMap($entity);
|
||||
|
||||
if (isset($this->_entityUpdates[$oid])) {
|
||||
unset($this->_entityUpdates[$oid]);
|
||||
}
|
||||
|
@ -66,6 +66,9 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
$this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($user));
|
||||
$this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph));
|
||||
$this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph2));
|
||||
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
|
||||
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph));
|
||||
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph2));
|
||||
}
|
||||
|
||||
public function testOneToManyAssociationModification()
|
||||
|
@ -252,5 +252,37 @@ class IdentityMapTest extends \Doctrine\Tests\OrmFunctionalTestCase
|
||||
// Now the collection should be refreshed with correct count
|
||||
$this->assertEquals(4, count($user2->getPhonenumbers()));
|
||||
}
|
||||
|
||||
public function testReusedSplObjectHashDoesNotConfuseUnitOfWork()
|
||||
{
|
||||
$hash1 = $this->subRoutine($this->_em);
|
||||
// Make sure cycles are collected NOW, because a PersistentCollection references
|
||||
// its owner, hence without forcing gc on cycles now the object will not (yet)
|
||||
// be garbage collected and thus the object hash is not reused.
|
||||
// This is not a memory leak!
|
||||
gc_collect_cycles();
|
||||
|
||||
$user1 = new CmsUser;
|
||||
$user1->status = 'dev';
|
||||
$user1->username = 'jwage';
|
||||
$user1->name = 'Jonathan W.';
|
||||
$hash2 = spl_object_hash($user1);
|
||||
$this->assertEquals($hash1, $hash2); // Hash reused!
|
||||
$this->_em->persist($user1);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
private function subRoutine($em) {
|
||||
$user = new CmsUser;
|
||||
$user->status = 'dev';
|
||||
$user->username = 'romanb';
|
||||
$user->name = 'Roman B.';
|
||||
$em->persist($user);
|
||||
$em->flush();
|
||||
$em->remove($user);
|
||||
$em->flush();
|
||||
|
||||
return spl_object_hash($user);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user