Commit ab0c7b11 authored by romanb's avatar romanb

[2.0][DDC-136] Some fixes to internal UnitOfWork logic.

parent 57a97eba
......@@ -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,16 +926,20 @@ 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]);
......@@ -1102,7 +1113,7 @@ class UnitOfWork implements PropertyChangedListener
if ($idHash === '') {
return false;
}
return isset($this->_identityMap[$classMetadata->rootEntityName][$idHash]);
}
......
......@@ -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);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment