From 616f2eda0af1a15ba205cc5013b5f001c34dfc55 Mon Sep 17 00:00:00 2001 From: "Roman S. Borschel" Date: Fri, 21 May 2010 11:49:05 +0200 Subject: [PATCH] [DDC-531] Fixed. --- .../ORM/Persisters/BasicEntityPersister.php | 6 +- .../ORM/Functional/Ticket/DDC531Test.php | 88 +++++++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 22388f4fb..08a7452a3 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -513,10 +513,12 @@ class BasicEntityPersister $targetClass = $this->_em->getClassMetadata($assoc->targetEntityName); if ($assoc->isOwningSide) { + $isInverseSingleValued = $assoc->inversedBy && ! $targetClass->isCollectionValuedAssociation($assoc->inversedBy); + // Mark inverse side as fetched in the hints, otherwise the UoW would // try to load it in a separate query (remember: to-one inverse sides can not be lazy). $hints = array(); - if ($assoc->inversedBy) { + if ($isInverseSingleValued) { $hints['fetched'][$targetClass->name][$assoc->inversedBy] = true; if ($targetClass->subClasses) { foreach ($targetClass->subClasses as $targetSubclassName) { @@ -533,7 +535,7 @@ class BasicEntityPersister $targetEntity = $this->load($identifier, $targetEntity, $assoc, $hints); // Complete bidirectional association, if necessary - if ($targetEntity !== null && $assoc->inversedBy && ! $targetClass->isCollectionValuedAssociation($assoc->inversedBy)) { + if ($targetEntity !== null && $isInverseSingleValued) { $targetClass->reflFields[$assoc->inversedBy]->setValue($targetEntity, $sourceEntity); } } else { diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php new file mode 100644 index 000000000..0ac3b9b8d --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC531Test.php @@ -0,0 +1,88 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC531Item'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC531SubItem'), + )); + } + + public function testIssue() + { + $item1 = new DDC531Item; + $item2 = new DDC531Item; + $item2->parent = $item1; + $item1->getChildren()->add($item2); + $this->_em->persist($item1); + $this->_em->persist($item2); + $this->_em->flush(); + $this->_em->clear(); + + $item3 = $this->_em->find(__NAMESPACE__ . '\DDC531Item', $item2->id); // Load child item first (id 2) + // parent will already be loaded, cannot be lazy because it has mapped subclasses and we would not + // know which proxy type to put in. + $this->assertTrue($item3->parent instanceof DDC531Item); + $this->assertFalse($item3->parent instanceof \Doctrine\ORM\Proxy\Proxy); + $item4 = $this->_em->find(__NAMESPACE__ . '\DDC531Item', $item1->id); // Load parent item (id 1) + $this->assertNull($item4->parent); + $this->assertNotNull($item4->getChildren()); + $this->assertTrue($item4->getChildren()->contains($item3)); // lazy-loads children + } +} + +/** + * @Entity + * @InheritanceType("SINGLE_TABLE") + * @DiscriminatorColumn(name="type", type="integer") + * @DiscriminatorMap({"0" = "DDC531Item", "1" = "DDC531SubItem"}) + */ +class DDC531Item +{ + /** + * @Id + * @Column(type="integer") + * @GeneratedValue(strategy="AUTO") + */ + public $id; + + /** + * @OneToMany(targetEntity="DDC531Item", mappedBy="parent") + */ + protected $children; + + /** + * @ManyToOne(targetEntity="DDC531Item", inversedBy="children") + * @JoinColumn(name="parentId", referencedColumnName="id") + */ + public $parent; + + public function __construct() + { + $this->children = new \Doctrine\Common\Collections\ArrayCollection; + } + + public function getParent() + { + return $this->parent; + } + + public function getChildren() + { + return $this->children; + } +} + +/** + * @Entity + */ +class DDC531SubItem extends DDC531Item +{ +} \ No newline at end of file