From 89d0a52c4f6848ea6feafd006c6d4258904dbf07 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Mon, 11 Oct 2010 22:15:18 +0200 Subject: [PATCH] DDC-833 - Fix some nasty bug occouring when re-creating an entity that was a proxy before. Also found another nasty issue with refreshing entity that had an already loaded many-to-many or one-to-many association. --- .../ORM/Persisters/BasicEntityPersister.php | 3 + lib/Doctrine/ORM/UnitOfWork.php | 10 +- .../ORM/Functional/BasicFunctionalTest.php | 107 +++++++++++++++++- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 51d5c5121..f7dacc53c 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -674,6 +674,9 @@ class BasicEntityPersister } } else if ($value instanceof PersistentCollection && $value->isInitialized()) { $value->setInitialized(false); + // no matter if dirty or non-dirty entities are already loaded, smoke them out! + // the beauty of it being, they are still in the identity map + $value->unwrap()->clear(); $newData[$field] = $value; } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index b6d0393d3..5b5782df8 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1929,14 +1929,12 @@ class UnitOfWork implements PropertyChangedListener } } else { // Inject collection - $reflField = $class->reflFields[$field]; - $pColl = new PersistentCollection( - $this->em, $targetClass, - //TODO: getValue might be superfluous once DDC-79 is implemented. - $reflField->getValue($entity) ?: new ArrayCollection - ); + $pColl = new PersistentCollection($this->em, $targetClass, new ArrayCollection); $pColl->setOwner($entity, $assoc); + + $reflField = $class->reflFields[$field]; $reflField->setValue($entity, $pColl); + if ($assoc['fetch'] == ClassMetadata::FETCH_LAZY) { $pColl->setInitialized(false); } else { diff --git a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php index 97414ab4e..7a7da0c7a 100644 --- a/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php @@ -3,6 +3,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\ORM\Tools\SchemaTool; +use Doctrine\ORM\Query; use Doctrine\Tests\Models\CMS\CmsUser; use Doctrine\Tests\Models\CMS\CmsPhonenumber; use Doctrine\Tests\Models\CMS\CmsAddress; @@ -263,7 +264,111 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->refresh($user); $this->assertEquals('developer', $user->status); } - + + /** + * @group DDC-833 + */ + public function testRefreshResetsCollection() + { + $user = new CmsUser; + $user->name = 'Guilherme'; + $user->username = 'gblanco'; + $user->status = 'developer'; + + // Add a phonenumber + $ph1 = new CmsPhonenumber; + $ph1->phonenumber = "12345"; + $user->addPhonenumber($ph1); + + // Add a phonenumber + $ph2 = new CmsPhonenumber; + $ph2->phonenumber = "54321"; + + $this->_em->persist($user); + $this->_em->persist($ph1); + $this->_em->persist($ph2); + $this->_em->flush(); + + $user->addPhonenumber($ph2); + + $this->assertEquals(2, count($user->phonenumbers)); + $this->_em->refresh($user); + + $this->assertEquals(1, count($user->phonenumbers)); + } + + /** + * @group DDC-833 + */ + public function testDqlRefreshResetsCollection() + { + $user = new CmsUser; + $user->name = 'Guilherme'; + $user->username = 'gblanco'; + $user->status = 'developer'; + + // Add a phonenumber + $ph1 = new CmsPhonenumber; + $ph1->phonenumber = "12345"; + $user->addPhonenumber($ph1); + + // Add a phonenumber + $ph2 = new CmsPhonenumber; + $ph2->phonenumber = "54321"; + + $this->_em->persist($user); + $this->_em->persist($ph1); + $this->_em->persist($ph2); + $this->_em->flush(); + + $user->addPhonenumber($ph2); + + $this->assertEquals(2, count($user->phonenumbers)); + $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1"; + $user = $this->_em->createQuery($dql) + ->setParameter(1, $user->id) + ->setHint(Query::HINT_REFRESH, true) + ->getSingleResult(); + + $this->assertEquals(1, count($user->phonenumbers)); + } + + /** + * @group DDC-833 + */ + public function testCreateEntityOfProxy() + { + $user = new CmsUser; + $user->name = 'Guilherme'; + $user->username = 'gblanco'; + $user->status = 'developer'; + + // Add a phonenumber + $ph1 = new CmsPhonenumber; + $ph1->phonenumber = "12345"; + $user->addPhonenumber($ph1); + + // Add a phonenumber + $ph2 = new CmsPhonenumber; + $ph2->phonenumber = "54321"; + + $this->_em->persist($user); + $this->_em->persist($ph1); + $this->_em->persist($ph2); + $this->_em->flush(); + $this->_em->clear(); + + $userId = $user->id; + $user = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $user->id); + + $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1"; + $user = $this->_em->createQuery($dql) + ->setParameter(1, $userId) + ->getSingleResult(); + + $this->assertEquals(1, count($user->phonenumbers)); + } + public function testAddToCollectionDoesNotInitialize() { $user = new CmsUser;