diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 134deb695..5eb139628 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -177,9 +177,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function hydrateAdd($element) { - if ( ! $this->contains($element)) { - $this->_coll->add($element); - } + $this->_coll->add($element); // If _backRefFieldName is set, then the association is bidirectional // and we need to set the back reference. @@ -206,9 +204,7 @@ final class PersistentCollection implements \Doctrine\Common\Collections\Collect */ public function hydrateSet($key, $element) { - if ( ! $this->contains($element)) { - $this->_coll->set($key, $element); - } + $this->_coll->set($key, $element); // If _backRefFieldName is set, then the association is bidirectional // and we need to set the back reference. diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index c65acdeba..e6ac73794 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -451,13 +451,10 @@ class UnitOfWork implements PropertyChangedListener $actualData[$name] = $refProp->getValue($entity); } - if ($class->isCollectionValuedAssociation($name) && $actualData[$name] !== null) { + if ($class->isCollectionValuedAssociation($name) && $actualData[$name] !== null + && ! ($actualData[$name] instanceof PersistentCollection)) { // If $actualData[$name] is Collection then unwrap the array if ( ! $actualData[$name] instanceof ArrayCollection) { - if ($actualData[$name] instanceof PersistentCollection) { - $actualData[$name] = $actualData[$name]->toArray(); - } - $actualData[$name] = new ArrayCollection($actualData[$name]); } @@ -1136,8 +1133,9 @@ class UnitOfWork implements PropertyChangedListener $visited[$oid] = $entity; // Mark visited - $class = $this->_em->getClassMetadata(get_class($entity)); - $entityState = $this->getEntityState($entity, self::STATE_NEW); + $class = $this->_em->getClassMetadata(get_class($entity)); + $entityState = $this->getEntityState($entity, self::STATE_NEW); + switch ($entityState) { case self::STATE_MANAGED: // Nothing to do, except if policy is "deferred explicit" diff --git a/tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php b/tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php index 2807be4e6..88b4a9098 100644 --- a/tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/StandardEntityPersisterTest.php @@ -3,7 +3,7 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\Tests\Models\ECommerce\ECommerceCart, - Doctrine\Tests\Models\ECommerce\ECommerceCategory, + Doctrine\Tests\Models\ECommerce\ECommerceFeature, Doctrine\Tests\Models\ECommerce\ECommerceCustomer, Doctrine\Tests\Models\ECommerce\ECommerceProduct; @@ -48,31 +48,40 @@ class StandardEntityPersisterTest extends \Doctrine\Tests\OrmFunctionalTestCase */ public function testAddPersistRetrieve() { - $category = new ECommerceCategory(); - $category->setName('Eletronics'); - - $product = new ECommerceProduct(); - $product->setName('MP3 Player Foo'); - $category->addProduct($product); - - $product2 = new ECommerceProduct(); - $product2->setName('MP3 Player Bar'); - $category->addProduct($product2); - - $this->_em->persist($category); + $f1 = new ECommerceFeature; + $f1->setDescription('AC-3'); + + $f2 = new ECommerceFeature; + $f2->setDescription('DTS'); + + $p = new ECommerceProduct; + $p->addFeature($f1); + $p->addfeature($f2); + $this->_em->persist($p); + $this->_em->flush(); - // He reported that using $this->_em->clear(); after flush fixes the problem. - // It should work out of the box. That's what we are testing. + $this->assertEquals(2, count($p->getFeatures())); + $this->assertTrue($p->getFeatures() instanceof \Doctrine\ORM\PersistentCollection); + + $q = $this->_em->createQuery( + 'SELECT p, f + FROM Doctrine\Tests\Models\ECommerce\ECommerceProduct p + JOIN p.features f' + ); - $q = $this->_em->createQuery(' - SELECT c, p - FROM Doctrine\Tests\Models\ECommerce\ECommerceCategory c - LEFT JOIN c.products p - '); $res = $q->getResult(); - $this->assertEquals(1, count($res)); - $this->assertEquals(2, count($res[0]->getProducts())); + $this->assertEquals(2, count($p->getFeatures())); + $this->assertTrue($p->getFeatures() instanceof \Doctrine\ORM\PersistentCollection); + + // Check that the features are the same instances still + foreach ($p->getFeatures() as $feature) { + if ($feature->getDescription() == 'AC-3') { + $this->assertTrue($feature === $f1); + } else { + $this->assertTrue($feature === $f2); + } + } } }