Skip to content

Commit

Permalink
Fix #4252 Cascade first before refreshing the entity itself so toMany…
Browse files Browse the repository at this point in the history
… associations are not reset to empty collections
  • Loading branch information
Zacharias Luiten committed Jun 8, 2018
1 parent 01f89a8 commit f7f7511
Show file tree
Hide file tree
Showing 2 changed files with 214 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/Doctrine/ORM/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -2149,12 +2149,12 @@ private function doRefresh($entity, array &$visited)
throw ORMInvalidArgumentException::entityNotManaged($entity);
}

$this->cascadeRefresh($entity, $visited);

$this->getEntityPersister($class->name)->refresh(
array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]),
$entity
);

$this->cascadeRefresh($entity, $visited);
}

/**
Expand Down
212 changes: 212 additions & 0 deletions tests/Doctrine/Tests/ORM/Functional/Ticket/GH4252Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<?php

namespace Doctrine\Tests\ORM\Functional\Ticket;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

/**
* @group GH-4252
*/
class GH4252Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();

$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(GH4252City::class),
$this->_em->getClassMetadata(GH4252Resident::class),
$this->_em->getClassMetadata(GH4252Address::class),
));
}

public function testIssue()
{
$city = new GH4252City([new GH4252Resident([new GH4252Address()])]);

$this->_em->persist($city);
$this->_em->flush();
$this->_em->clear();

/** @var GH4252City $city */
$city = $this->_em->find(GH4252City::class, $city->getId());
$city->setFlag(false);
/** @var GH4252Resident $resident */
$resident = $city->getResidents()->first();
$resident->setFlag(false);
/** @var GH4252Address $address */
$address = $resident->getAddresses()->first();
$address->setFlag(false);

$this->_em->refresh($city);

$resident = $city->getResidents()->first();
$address = $resident->getAddresses()->first();

$this->assertTrue($city->getFlag());
$this->assertTrue($resident->getFlag());
$this->assertTrue($address->getFlag());
}
}

/**
* @Entity
*/
class GH4252City
{
/**
* @var int
* @Id @Column(type="integer") @GeneratedValue
*/
private $id;

/**
* @var bool
* @Column(type="boolean")
*/
private $flag;

/**
* @var GH4252Resident[]|Collection
*
* @OneToMany(targetEntity="Doctrine\Tests\ORM\Functional\Ticket\GH4252Resident", mappedBy="city", cascade={"persist","refresh"})
*/
private $residents;

public function __construct(array $residents)
{
$this->residents = new ArrayCollection();
foreach ($residents as $resident) {
$this->residents->add($resident);
$resident->setCity($this);
}
$this->flag = true;
}

public function getId() : int
{
return $this->id;
}

public function getFlag() : bool
{
return $this->flag;
}

public function setFlag(bool $flag) : void
{
$this->flag = $flag;
}

public function getResidents() : Collection
{
return $this->residents;
}
}

/**
* @Entity
*/
class GH4252Resident
{
/**
* @var int
* @Id @Column(type="integer") @GeneratedValue
*/
private $id;

/**
* @var GH4252City
* @ManyToOne(targetEntity="Doctrine\Tests\ORM\Functional\Ticket\GH4252City", inversedBy="residents")
*/
private $city;

/**
* @var bool
* @Column(type="boolean")
*/
private $flag;

/**
* @var GH4252Address[]|Collection
*
* @ManyToMany(targetEntity="Doctrine\Tests\ORM\Functional\Ticket\GH4252Address", fetch="EXTRA_LAZY", cascade={"persist","refresh"})
*/
private $addresses;

public function __construct(array $addresses)
{
$this->addresses = new ArrayCollection();
foreach ($addresses as $address) {
$this->addresses->add($address);
}
$this->flag = true;
}

public function getId() : int
{
return $this->id;
}

public function getCity() : GH4252City
{
return $this->city;
}

public function setCity(GH4252City $city) : void
{
$this->city = $city;
}

public function getFlag() : bool
{
return $this->flag;
}

public function setFlag(bool $flag) : void
{
$this->flag = $flag;
}

public function getAddresses() : Collection
{
return $this->addresses;
}
}

/** @Entity */
class GH4252Address
{
/**
* @var int
* @Id @Column(type="integer") @GeneratedValue
*/
private $id;

/**
* @var bool
* @Column(type="boolean")
*/
private $flag;

public function __construct()
{
$this->flag = true;
}

public function getId() : int
{
return $this->id;
}

public function getFlag() : bool
{
return $this->flag;
}

public function setFlag(bool $flag) : void
{
$this->flag = $flag;
}
}

0 comments on commit f7f7511

Please sign in to comment.