From be24439e2f69f3fb2b0370e9587fce558c23dd39 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 23 Feb 2013 01:44:58 +0100 Subject: [PATCH 1/2] Adding failing test for DDC-2230 Proxies that implement the Doctrine\Common\PropertyChangedListener are getting eagerly initialized because the UnitOfWork injects itself into them after they are created. The test currently fails for what described above, and also verifies if the UoW is correctly injected in the proxy during lazy loading. --- .../ORM/Functional/Ticket/DDC2230Test.php | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php new file mode 100644 index 000000000..9b69fe50f --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC2230Test.php @@ -0,0 +1,102 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2230User'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC2230Address'), + )); + } catch (ToolsException $e) {} + } + + public function testNotifyTrackingNotCalledOnUninitializedProxies() + { + $insertedUser = new DDC2230User(); + $insertedUser->address = new DDC2230Address(); + + $this->_em->persist($insertedUser); + $this->_em->persist($insertedUser->address); + $this->_em->flush(); + $this->_em->clear(); + + $user = $this->_em->find(__NAMESPACE__ . '\\DDC2230User', $insertedUser->id); + + $this->_em->clear(); + + $mergedUser = $this->_em->merge($user); + + /* @var $address \Doctrine\Common\Proxy\Proxy */ + $address = $mergedUser->address; + + $this->assertInstanceOf('Doctrine\\ORM\\Proxy\\Proxy', $address); + $this->assertFalse($address->__isInitialized()); + } + + public function testNotifyTrackingCalledOnProxyInitialization() + { + $insertedAddress = new DDC2230Address(); + + $this->_em->persist($insertedAddress); + $this->_em->flush(); + $this->_em->clear(); + + $addressProxy = $this->_em->getReference(__NAMESPACE__ . '\\DDC2230Address', $insertedAddress->id); + + /* @var $addressProxy \Doctrine\Common\Proxy\Proxy|\Doctrine\Tests\ORM\Functional\Ticket\DDC2230Address */ + $this->assertFalse($addressProxy->__isInitialized()); + $this->assertNull($addressProxy->listener); + + $addressProxy->__load(); + + $this->assertSame($this->_em->getUnitOfWork(), $addressProxy->listener); + } +} + +/** @Entity */ +class DDC2230User +{ + /** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */ + public $id; + + /** + * @OneToOne(targetEntity="DDC2230Address") + */ + public $address; +} + +/** + * @Entity + * @ChangeTrackingPolicy("NOTIFY") + */ +class DDC2230Address implements NotifyPropertyChanged +{ + /** @Id @Column(type="integer") @GeneratedValue(strategy="AUTO") */ + public $id; + + /** + * @var \Doctrine\Common\PropertyChangedListener + */ + public $listener; + + /** {@inheritDoc} */ + function addPropertyChangedListener(PropertyChangedListener $listener) + { + $this->listener = $listener; + } +} + From 350fa4f15b95f28fbbe3ff06237a17ebf24de67e Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 23 Feb 2013 01:45:40 +0100 Subject: [PATCH 2/2] Applying fix for failing test for DDC-2230 --- lib/Doctrine/ORM/UnitOfWork.php | 7 +++++-- .../Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 9848499d9..c07afc173 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -2659,7 +2659,10 @@ class UnitOfWork implements PropertyChangedListener $this->entityIdentifiers[$newValueOid] = $associatedId; $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue; - if ($newValue instanceof NotifyPropertyChanged) { + if ( + $newValue instanceof NotifyPropertyChanged && + ( ! $newValue instanceof Proxy || $newValue->__isInitialized()) + ) { $newValue->addPropertyChangedListener($this); } $this->entityStates[$newValueOid] = self::STATE_MANAGED; @@ -3003,7 +3006,7 @@ class UnitOfWork implements PropertyChangedListener $this->addToIdentityMap($entity); - if ($entity instanceof NotifyPropertyChanged) { + if ($entity instanceof NotifyPropertyChanged && ( ! $entity instanceof Proxy || $entity->__isInitialized())) { $entity->addPropertyChangedListener($this); } } diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php index ab5d2934a..fd2288eed 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php @@ -50,7 +50,14 @@ class DDC1690Test extends \Doctrine\Tests\OrmFunctionalTestCase $child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId); $this->assertEquals(1, count($parent->listeners)); - $this->assertEquals(1, count($child->listeners)); + $this->assertInstanceOf( + 'Doctrine\\ORM\\Proxy\\Proxy', + $child, + 'Verifying that $child is a proxy before using proxy API' + ); + $this->assertCount(0, $child->listeners); + $child->__load(); + $this->assertCount(1, $child->listeners); unset($parent, $child); $parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId);