From 56279938276e0449419988cbb60d54c9897962d6 Mon Sep 17 00:00:00 2001 From: Patrick Schwisow Date: Thu, 20 Dec 2012 15:31:46 -0600 Subject: [PATCH 1/3] Fix DDC-1690 Added the lines suggested by the original reporter. --- lib/Doctrine/ORM/UnitOfWork.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 75e7a3501..e6ab95321 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -2573,6 +2573,9 @@ class UnitOfWork implements PropertyChangedListener $newValueOid = spl_object_hash($newValue); $this->entityIdentifiers[$newValueOid] = $associatedId; $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue; + if ($newValue instanceof NotifyPropertyChanged) { + $newValue->addPropertyChangedListener($this); + } $this->entityStates[$newValueOid] = self::STATE_MANAGED; // make sure that when an proxy is then finally loaded, $this->originalEntityData is set also! break; From bc6921504ae34fa8a4621bb3e099b1a0bceeeff9 Mon Sep 17 00:00:00 2001 From: Patrick Schwisow Date: Fri, 21 Dec 2012 14:32:10 -0600 Subject: [PATCH 2/3] [DDC-1690] Created unit test --- .../ORM/Functional/Ticket/DDC1690Test.php | 153 ++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php new file mode 100644 index 000000000..ab5d2934a --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1690Test.php @@ -0,0 +1,153 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Parent'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1690Child') + )); + } catch (\Exception $e) { + // Swallow all exceptions. We do not test the schema tool here. + } + } + + public function testChangeTracking() + { + $parent = new DDC1690Parent(); + $child = new DDC1690Child(); + $parent->setName('parent'); + $child->setName('child'); + + $parent->setChild($child); + $child->setParent($parent); + + $this->_em->persist($parent); + $this->_em->persist($child); + + $this->assertEquals(1, count($parent->listeners)); + $this->assertEquals(1, count($child->listeners)); + + $this->_em->flush(); + $this->_em->clear(); + + $this->assertEquals(1, count($parent->listeners)); + $this->assertEquals(1, count($child->listeners)); + + $parentId = $parent->getId(); + $childId = $child->getId(); + unset($parent, $child); + + $parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId); + $child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId); + + $this->assertEquals(1, count($parent->listeners)); + $this->assertEquals(1, count($child->listeners)); + unset($parent, $child); + + $parent = $this->_em->find(__NAMESPACE__.'\DDC1690Parent', $parentId); + $child = $parent->getChild(); + + $this->assertEquals(1, count($parent->listeners)); + $this->assertEquals(1, count($child->listeners)); + unset($parent, $child); + + $child = $this->_em->find(__NAMESPACE__.'\DDC1690Child', $childId); + $parent = $child->getParent(); + + $this->assertEquals(1, count($parent->listeners)); + $this->assertEquals(1, count($child->listeners)); + } +} + +class NotifyBaseEntity implements NotifyPropertyChanged { + public $listeners = array(); + + public function addPropertyChangedListener(PropertyChangedListener $listener) { + if (!in_array($listener, $this->listeners)) { + $this->listeners[] = $listener; + } + } + + protected function onPropertyChanged($propName, $oldValue, $newValue) { + if ($this->listeners) { + foreach ($this->listeners as $listener) { + $listener->propertyChanged($this, $propName, $oldValue, $newValue); + } + } + } +} + +/** @Entity @ChangeTrackingPolicy("NOTIFY") */ +class DDC1690Parent extends NotifyBaseEntity { + /** @Id @Column(type="integer") @GeneratedValue */ + private $id; + + /** @Column */ + private $name; + + /** @OneToOne(targetEntity="DDC1690Child") */ + private $child; + + function getId() { + return $this->id; + } + + function getName() { + return $this->name; + } + + function setName($name) { + $this->onPropertyChanged('name', $this->name, $name); + $this->name = $name; + } + + function setChild($child) { + $this->child = $child; + } + + function getChild() { + return $this->child; + } +} + +/** @Entity */ +class DDC1690Child extends NotifyBaseEntity { + /** @Id @Column(type="integer") @GeneratedValue */ + private $id; + + /** @Column */ + private $name; + + /** @OneToOne(targetEntity="DDC1690Parent", mappedBy="child") */ + private $parent; + + function getId() { + return $this->id; + } + + function getName() { + return $this->name; + } + + function setName($name) { + $this->onPropertyChanged('name', $this->name, $name); + $this->name = $name; + } + + function setParent($parent) { + $this->parent = $parent; + } + + function getParent() { + return $this->parent; + } +} \ No newline at end of file From 0b21046fce6312be094ca34df3a20da1d14d93f3 Mon Sep 17 00:00:00 2001 From: Patrick Schwisow Date: Fri, 21 Dec 2012 15:35:32 -0600 Subject: [PATCH 3/3] [DDC-1690] Added an empty line as requested. --- lib/Doctrine/ORM/UnitOfWork.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index e6ab95321..0795c3ad0 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -2573,6 +2573,7 @@ class UnitOfWork implements PropertyChangedListener $newValueOid = spl_object_hash($newValue); $this->entityIdentifiers[$newValueOid] = $associatedId; $this->identityMap[$targetClass->rootEntityName][$relatedIdHash] = $newValue; + if ($newValue instanceof NotifyPropertyChanged) { $newValue->addPropertyChangedListener($this); }