1
0
mirror of synced 2024-12-04 18:56:06 +03:00

[DDC-2624] Fix bug when persistent collection is cloned and used in a new entity.

This commit is contained in:
Benjamin Eberlei 2014-02-09 14:27:23 +01:00
parent 3c2b626102
commit 53a5a48aed
3 changed files with 50 additions and 2 deletions

View File

@ -560,7 +560,15 @@ class UnitOfWork implements PropertyChangedListener
foreach ($class->reflFields as $name => $refProp) {
$value = $refProp->getValue($entity);
if ($class->isCollectionValuedAssociation($name) && $value !== null && ! ($value instanceof PersistentCollection)) {
if ($class->isCollectionValuedAssociation($name) && $value !== null) {
if ($value instanceof PersistentCollection) {
if ($value->getOwner() === $entity) {
continue;
}
$value = new ArrayCollection($value->getValues());
}
// If $value is not a Collection then use an ArrayCollection.
if ( ! $value instanceof Collection) {
$value = new ArrayCollection($value);

View File

@ -137,6 +137,11 @@ class ECommerceProduct
}
}
public function setCategories($categories)
{
$this->categories = $categories;
}
public function getCategories()
{
return $this->categories;
@ -166,6 +171,9 @@ class ECommerceProduct
public function __clone()
{
$this->isCloned = true;
if ($this->categories) {
$this->categories = clone $this->categories;
}
}
/**

View File

@ -12,6 +12,12 @@ use Doctrine\Tests\Models\ECommerce\ECommerceProduct;
*/
class DDC2074Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('ecommerce');
parent::setUp();
}
public function testShouldNotScheduleDeletionOnClonedInstances()
{
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\ECommerce\ECommerceProduct');
@ -26,4 +32,30 @@ class DDC2074Test extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, count($uow->getScheduledCollectionDeletions()));
}
}
public function testSavingClonedPersistentCollection()
{
$product = new ECommerceProduct();
$category = new ECommerceCategory();
$category->setName('foo');
$product->addCategory($category);
$this->_em->persist($product);
$this->_em->persist($category);
$this->_em->flush();
$newProduct = clone $product;
$this->_em->persist($newProduct);
$this->_em->flush();
$this->_em->clear();
$product1 = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $product->getId());
$product2 = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $newProduct->getId());
$this->assertCount(1, $product1->getCategories());
$this->assertCount(1, $product2->getCategories());
$this->assertSame($product1->getCategories()->get(0), $product2->getCategories()->get(0));
}
}