1
0
mirror of synced 2024-12-13 22:56:04 +03:00

Fixed DDC-1608. Non-initialized PersistentCollection methods removeElement and contains now deal correctly with managed entities.

This commit is contained in:
Guilherme Blanco 2012-01-18 01:04:25 -05:00
parent c1012f7970
commit d39760ba49
4 changed files with 106 additions and 70 deletions

View File

@ -253,10 +253,15 @@ class ManyToManyPersister extends AbstractCollectionPersister
{ {
$uow = $this->_em->getUnitOfWork(); $uow = $this->_em->getUnitOfWork();
// shortcut for new entities // Shortcut for new entities
$entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW); $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
if ($entityState === UnitOfWork::STATE_NEW ||
($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element))) { if ($entityState === UnitOfWork::STATE_NEW) {
return false;
}
// Entity is scheduled for inclusion
if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
return false; return false;
} }
@ -277,7 +282,15 @@ class ManyToManyPersister extends AbstractCollectionPersister
$uow = $this->_em->getUnitOfWork(); $uow = $this->_em->getUnitOfWork();
// shortcut for new entities // shortcut for new entities
if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) === UnitOfWork::STATE_NEW) { $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
if ($entityState === UnitOfWork::STATE_NEW) {
return false;
}
// If Entity is scheduled for inclusion, it is not in this collection.
// We can assure that because it would have return true before on array check
if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
return false; return false;
} }

View File

@ -159,7 +159,14 @@ class OneToManyPersister extends AbstractCollectionPersister
$uow = $this->_em->getUnitOfWork(); $uow = $this->_em->getUnitOfWork();
// shortcut for new entities // shortcut for new entities
if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) == UnitOfWork::STATE_NEW) { $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
if ($entityState === UnitOfWork::STATE_NEW) {
return false;
}
// Entity is scheduled for inclusion
if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
return false; return false;
} }
@ -168,7 +175,7 @@ class OneToManyPersister extends AbstractCollectionPersister
// only works with single id identifier entities. Will throw an // only works with single id identifier entities. Will throw an
// exception in Entity Persisters if that is not the case for the // exception in Entity Persisters if that is not the case for the
// 'mappedBy' field. // 'mappedBy' field.
$id = current( $uow->getEntityIdentifier($coll->getOwner()) ); $id = current( $uow->getEntityIdentifier($coll->getOwner()));
return $persister->exists($element, array($mapping['mappedBy'] => $id)); return $persister->exists($element, array($mapping['mappedBy'] => $id));
} }
@ -183,7 +190,15 @@ class OneToManyPersister extends AbstractCollectionPersister
$uow = $this->_em->getUnitOfWork(); $uow = $this->_em->getUnitOfWork();
// shortcut for new entities // shortcut for new entities
if ($uow->getEntityState($element, UnitOfWork::STATE_NEW) == UnitOfWork::STATE_NEW) { $entityState = $uow->getEntityState($element, UnitOfWork::STATE_NEW);
if ($entityState === UnitOfWork::STATE_NEW) {
return false;
}
// If Entity is scheduled for inclusion, it is not in this collection.
// We can assure that because it would have return true before on array check
if ($entityState === UnitOfWork::STATE_MANAGED && $uow->isScheduledForInsert($element)) {
return false; return false;
} }

View File

@ -64,7 +64,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
/** /**
* @group DDC-546 * @group DDC-546
*/ */
public function testCountWhenNewEntitysPresent() public function testCountWhenNewEntityPresent()
{ {
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId); $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
@ -223,13 +223,15 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId); $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
$this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
$article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId); // Test One to Many existance retrieved from DB
$article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
$this->assertTrue($user->articles->contains($article)); $this->assertTrue($user->articles->contains($article));
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount()); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
// Test One to Many existance with state new
$article = new \Doctrine\Tests\Models\CMS\CmsArticle(); $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->topic = "Testnew"; $article->topic = "Testnew";
$article->text = "blub"; $article->text = "blub";
@ -238,12 +240,26 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertFalse($user->articles->contains($article)); $this->assertFalse($user->articles->contains($article));
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed."); $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
// Test One to Many existance with state clear
$this->_em->persist($article); $this->_em->persist($article);
$this->_em->flush(); $this->_em->flush();
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
$this->assertFalse($user->articles->contains($article)); $this->assertFalse($user->articles->contains($article));
$this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed."); $this->assertEquals($queryCount+1, $this->getCurrentQueryCount(), "Checking for contains of persisted entity should cause one query to be executed.");
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test One to Many existance with state managed
$article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->topic = "How to not fail anymore on tests";
$article->text = "That is simple! Just write more tests!";
$this->_em->persist($article);
$queryCount = $this->getCurrentQueryCount();
$this->assertFalse($user->articles->contains($article));
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of managed entity (but not persisted) should cause no query to be executed.");
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
} }
@ -255,6 +271,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId); $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
$this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
// Test Many to Many existance retrieved from DB
$group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId); $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
@ -262,6 +279,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed."); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many existance with state new
$group = new \Doctrine\Tests\Models\CMS\CmsGroup(); $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
$group->name = "A New group!"; $group->name = "A New group!";
@ -271,13 +289,26 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed."); $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of new entity should cause no query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many existance with state clear
$this->_em->persist($group); $this->_em->persist($group);
$this->_em->flush(); $this->_em->flush();
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
$this->assertFalse($user->groups->contains($group)); $this->assertFalse($user->groups->contains($group));
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of managed entity should cause one query to be executed."); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Checking for contains of persisted entity should cause one query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many existance with state managed
$group = new \Doctrine\Tests\Models\CMS\CmsGroup();
$group->name = "My managed group";
$this->_em->persist($group);
$queryCount = $this->getCurrentQueryCount();
$this->assertFalse($user->groups->contains($group));
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Checking for contains of managed entity (but not persisted) should cause no query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
} }
@ -313,6 +344,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId); $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
$this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Pre-Condition: Collection is not initialized.");
// Test One to Many removal with Entity retrieved from DB
$article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId); $article = $this->_em->find('Doctrine\Tests\Models\CMS\CmsArticle', $this->articleId);
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
@ -321,6 +353,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount()); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount());
// Test One to Many removal with Entity state as new
$article = new \Doctrine\Tests\Models\CMS\CmsArticle(); $article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->topic = "Testnew"; $article->topic = "Testnew";
$article->text = "blub"; $article->text = "blub";
@ -331,6 +364,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a new entity should cause no query to be executed."); $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a new entity should cause no query to be executed.");
// Test One to Many removal with Entity state as clean
$this->_em->persist($article); $this->_em->persist($article);
$this->_em->flush(); $this->_em->flush();
@ -338,8 +372,21 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user->articles->removeElement($article); $user->articles->removeElement($article);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a managed entity should cause one query to be executed."); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
$this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test One to Many removal with Entity state as managed
$article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->topic = "How to not fail anymore on tests";
$article->text = "That is simple! Just write more tests!";
$this->_em->persist($article);
$queryCount = $this->getCurrentQueryCount();
$user->articles->removeElement($article);
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed.");
} }
/** /**
@ -350,14 +397,16 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId); $user = $this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $this->userId);
$this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Pre-Condition: Collection is not initialized.");
// Test Many to Many removal with Entity retrieved from DB
$group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId); $group = $this->_em->find('Doctrine\Tests\Models\CMS\CmsGroup', $this->groupId);
$queryCount = $this->getCurrentQueryCount(); $queryCount = $this->getCurrentQueryCount();
$user->groups->removeElement($group); $user->groups->removeElement($group);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a managed entity should cause one query to be executed."); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many removal with Entity state as new
$group = new \Doctrine\Tests\Models\CMS\CmsGroup(); $group = new \Doctrine\Tests\Models\CMS\CmsGroup();
$group->name = "A New group!"; $group->name = "A New group!";
@ -368,6 +417,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing new entity should cause no query to be executed."); $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing new entity should cause no query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many removal with Entity state as clean
$this->_em->persist($group); $this->_em->persist($group);
$this->_em->flush(); $this->_em->flush();
@ -375,7 +425,20 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user->groups->removeElement($group); $user->groups->removeElement($group);
$this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a managed entity should cause one query to be executed."); $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
// Test Many to Many removal with Entity state as managed
$group = new \Doctrine\Tests\Models\CMS\CmsGroup();
$group->name = "A New group!";
$this->_em->persist($group);
$queryCount = $this->getCurrentQueryCount();
$user->groups->removeElement($group);
$this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed.");
$this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized."); $this->assertFalse($user->groups->isInitialized(), "Post-Condition: Collection is not initialized.");
} }

View File

@ -1,55 +0,0 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../TestInit.php';
/**
*
*/
class ManyToManyExtraLazyContainsTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('company');
parent::setUp();
}
public function testManyToManyExtraLazyContainsAddedPendingInsertEntityIsTrue()
{
$contract = new \Doctrine\Tests\Models\Company\CompanyFlexContract();
$this->_em->persist($contract);
$this->_em->flush();
$this->_em->clear();
$contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexContract', $contract->getId());
$pendingInsertManager = new \Doctrine\Tests\Models\Company\CompanyManager();
$this->_em->persist($pendingInsertManager);
$contract->getManagers()->add($pendingInsertManager);
$result = $contract->getManagers()->contains($pendingInsertManager);
$this->assertTrue($result);
}
public function testManyToManyExtraLazyContainsNonAddedPendingInsertEntityIsFalse()
{
$contract = new \Doctrine\Tests\Models\Company\CompanyFlexContract();
$this->_em->persist($contract);
$this->_em->flush();
$this->_em->clear();
$contract = $this->_em->find('Doctrine\Tests\Models\Company\CompanyFlexContract', $contract->getId());
$pendingInsertManager = new \Doctrine\Tests\Models\Company\CompanyManager();
$this->_em->persist($pendingInsertManager);
$result = $contract->getManagers()->contains($pendingInsertManager);
$this->assertFalse($result);
}
}