From 65ed6a2c2f93a9de6b6998fb2023bfd3de1d9467 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:19:01 +0200 Subject: [PATCH 01/23] #6613 #6614 simplifying entity definition - using auto-assigned string identifiers to reduce moving parts --- tests/Doctrine/Tests/Models/DDC6613/Phone.php | 30 +++++++++++++ tests/Doctrine/Tests/Models/DDC6613/User.php | 44 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 tests/Doctrine/Tests/Models/DDC6613/Phone.php create mode 100644 tests/Doctrine/Tests/Models/DDC6613/User.php diff --git a/tests/Doctrine/Tests/Models/DDC6613/Phone.php b/tests/Doctrine/Tests/Models/DDC6613/Phone.php new file mode 100644 index 000000000..9ce090960 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC6613/Phone.php @@ -0,0 +1,30 @@ + + * Date: 11.08.2017 + * Time: 13:12 + */ + +namespace Doctrine\Tests\Models\DDC6613; + + +/** + * @Table(name="ddc6613_phone") + */ + +class Phone +{ + + /** + * @Id + * @GeneratedValue(strategy="NONE") + * @Column(type="integer") + */ + public $id; + + public function __construct() + { + $this->id = uniqid('phone', true); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/DDC6613/User.php b/tests/Doctrine/Tests/Models/DDC6613/User.php new file mode 100644 index 000000000..6b233c0a2 --- /dev/null +++ b/tests/Doctrine/Tests/Models/DDC6613/User.php @@ -0,0 +1,44 @@ + + * Date: 11.08.2017 + * Time: 13:12 + */ + +namespace Doctrine\Tests\Models\DDC6613; + + +use Doctrine\Common\Collections\ArrayCollection; + +/** + * @Entity() + * @Table(name="ddc6613_user") + */ +class User +{ + + /** + * @Id + * @GeneratedValue(strategy="NONE") + * @Column(type="string") + */ + private $id; + + + /** + * @ManyToMany(targetEntity="Phone", fetch="LAZY", cascade={"remove", "detach"}) + */ + public $phones; + + /** + * User constructor. + */ + public function __construct() + { + $this->id = uniqid('user', true); + $this->phones = new ArrayCollection(); + } + + +} \ No newline at end of file From 64a1251b612633e2823d985b490bdb0315d76d6e Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:20:07 +0200 Subject: [PATCH 02/23] #6613 #6614 better test specification - removing useless assertions --- tests/Doctrine/Tests/Models/DDC6613/User.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/Doctrine/Tests/Models/DDC6613/User.php b/tests/Doctrine/Tests/Models/DDC6613/User.php index 6b233c0a2..9475bef4b 100644 --- a/tests/Doctrine/Tests/Models/DDC6613/User.php +++ b/tests/Doctrine/Tests/Models/DDC6613/User.php @@ -31,9 +31,6 @@ class User */ public $phones; - /** - * User constructor. - */ public function __construct() { $this->id = uniqid('user', true); From 85dc707cc8b679c7dba957b19c30225856ef5fcd Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:21:56 +0200 Subject: [PATCH 03/23] #6613 #6614 smashing entity definitions into the test --- .../ORM/Functional/Ticket/DDC6613Test.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php new file mode 100644 index 000000000..30e4f5276 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -0,0 +1,127 @@ + + * Date: 11.08.2017 + * Time: 12:28 + */ + +namespace Doctrine\Tests\ORM\Functional\Ticket; + + +use Doctrine\DBAL\Schema\SchemaException; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Embeddable; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\PersistentCollection; +use Doctrine\ORM\Proxy\Proxy; +use Doctrine\Tests\Models\DDC6613\Phone; +use Doctrine\Tests\Models\DDC6613\User; + + +class DDC6613Test extends \Doctrine\Tests\OrmFunctionalTestCase +{ + + public function setUp() + { + parent::setUp(); + + try { + $this->setUpEntitySchema( + [ + DDC6613Phone::class, + DDC6613User::class + ] + ); + } catch (SchemaException $e) { + } + } + + public function testFail() + { + $user = new DDC6613User(); + $this->_em->persist($user); + $this->_em->flush(); + + $this->_em->clear(); + + /** @var User $user */ + $user = $this->_em->find(User::class, 1); + $phone1 = new DDC6613Phone(); + $phones = $user->phones; + $user->phones->add($phone1); + $this->_em->persist($phone1); + $this->_em->flush(); + + $phone2 = new DDC6613Phone(); + $user->phones->add($phone2); + $this->_em->persist($phone2); + + /* @var $phones PersistentCollection */ +// $phones = $user->phones; + + self::assertInstanceOf(PersistentCollection::class, $phones); + self::assertFalse($phones->isInitialized()); + + $phones->initialize(); + + self::assertTrue($phones->isInitialized()); + self::assertCount(2, $phones); + + $this->_em->flush(); + + self::assertFalse($phones->isDirty()); + self::assertTrue($phones->isInitialized()); + self::assertCount(2, $user->phones); + } + +} + +/** + * @Entity + * @Table(name="ddc6613_user") + */ +class DDC6613User +{ + /** + * @Id + * @GeneratedValue(strategy="NONE") + * @Column(type="string") + */ + private $id; + + /** + * @ManyToMany(targetEntity="Phone", fetch="LAZY", cascade={"remove", "detach"}) + */ + public $phones; + + public function __construct() + { + $this->id = uniqid('user', true); + $this->phones = new ArrayCollection(); + } + + +} + +/** + * @Table(name="ddc6613_phone") + */ +class DDC6613Phone +{ + + /** + * @Id + * @GeneratedValue(strategy="NONE") + * @Column(type="integer") + */ + public $id; + + public function __construct() + { + $this->id = uniqid('phone', true); + } +} \ No newline at end of file From 5c5c8fc48720f1eb69e1198a77683f18c8346786 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:22:31 +0200 Subject: [PATCH 04/23] #6613 #6614 removing dedicated DDC6613 model directory --- tests/Doctrine/Tests/Models/DDC6613/Phone.php | 30 -------------- tests/Doctrine/Tests/Models/DDC6613/User.php | 41 ------------------- 2 files changed, 71 deletions(-) delete mode 100644 tests/Doctrine/Tests/Models/DDC6613/Phone.php delete mode 100644 tests/Doctrine/Tests/Models/DDC6613/User.php diff --git a/tests/Doctrine/Tests/Models/DDC6613/Phone.php b/tests/Doctrine/Tests/Models/DDC6613/Phone.php deleted file mode 100644 index 9ce090960..000000000 --- a/tests/Doctrine/Tests/Models/DDC6613/Phone.php +++ /dev/null @@ -1,30 +0,0 @@ - - * Date: 11.08.2017 - * Time: 13:12 - */ - -namespace Doctrine\Tests\Models\DDC6613; - - -/** - * @Table(name="ddc6613_phone") - */ - -class Phone -{ - - /** - * @Id - * @GeneratedValue(strategy="NONE") - * @Column(type="integer") - */ - public $id; - - public function __construct() - { - $this->id = uniqid('phone', true); - } -} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/DDC6613/User.php b/tests/Doctrine/Tests/Models/DDC6613/User.php deleted file mode 100644 index 9475bef4b..000000000 --- a/tests/Doctrine/Tests/Models/DDC6613/User.php +++ /dev/null @@ -1,41 +0,0 @@ - - * Date: 11.08.2017 - * Time: 13:12 - */ - -namespace Doctrine\Tests\Models\DDC6613; - - -use Doctrine\Common\Collections\ArrayCollection; - -/** - * @Entity() - * @Table(name="ddc6613_user") - */ -class User -{ - - /** - * @Id - * @GeneratedValue(strategy="NONE") - * @Column(type="string") - */ - private $id; - - - /** - * @ManyToMany(targetEntity="Phone", fetch="LAZY", cascade={"remove", "detach"}) - */ - public $phones; - - public function __construct() - { - $this->id = uniqid('user', true); - $this->phones = new ArrayCollection(); - } - - -} \ No newline at end of file From 693a0546d31f8a7e5876e2fa76cb998af9a87c1f Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:23:21 +0200 Subject: [PATCH 05/23] #6613 #6614 CS - applying `@group` annotation to the test --- .../ORM/Functional/Ticket/DDC6613Test.php | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 30e4f5276..16d21bbd1 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -8,23 +8,21 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; - +use Doctrine\Common\Collections\ArrayCollection; use Doctrine\DBAL\Schema\SchemaException; use Doctrine\ORM\Mapping\Column; -use Doctrine\ORM\Mapping\Embeddable; use Doctrine\ORM\Mapping\Entity; -use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\GeneratedValue; -use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\PersistentCollection; -use Doctrine\ORM\Proxy\Proxy; -use Doctrine\Tests\Models\DDC6613\Phone; -use Doctrine\Tests\Models\DDC6613\User; +use Doctrine\Tests\OrmFunctionalTestCase; - -class DDC6613Test extends \Doctrine\Tests\OrmFunctionalTestCase +/** + * @group #6613 + * @group #6614 + */ +class DDC6613Test extends OrmFunctionalTestCase { - public function setUp() { parent::setUp(); @@ -33,7 +31,7 @@ class DDC6613Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->setUpEntitySchema( [ DDC6613Phone::class, - DDC6613User::class + DDC6613User::class, ] ); } catch (SchemaException $e) { @@ -49,7 +47,7 @@ class DDC6613Test extends \Doctrine\Tests\OrmFunctionalTestCase $this->_em->clear(); /** @var User $user */ - $user = $this->_em->find(User::class, 1); + $user = $this->_em->find(User::class, 1); $phone1 = new DDC6613Phone(); $phones = $user->phones; $user->phones->add($phone1); @@ -77,7 +75,6 @@ class DDC6613Test extends \Doctrine\Tests\OrmFunctionalTestCase self::assertTrue($phones->isInitialized()); self::assertCount(2, $user->phones); } - } /** @@ -103,8 +100,6 @@ class DDC6613User $this->id = uniqid('user', true); $this->phones = new ArrayCollection(); } - - } /** @@ -112,7 +107,6 @@ class DDC6613User */ class DDC6613Phone { - /** * @Id * @GeneratedValue(strategy="NONE") From 8b185eb8221e15a58b74a8e3e6453f66a3a5c1b9 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:27:34 +0200 Subject: [PATCH 06/23] #6613 #6614 rewrote test logic to be less magic-constant-dependent --- .../ORM/Functional/Ticket/DDC6613Test.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 16d21bbd1..5c3e0c039 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -10,10 +10,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\DBAL\Schema\SchemaException; -use Doctrine\ORM\Mapping\Column; -use Doctrine\ORM\Mapping\Entity; -use Doctrine\ORM\Mapping\GeneratedValue; -use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\PersistentCollection; use Doctrine\Tests\OrmFunctionalTestCase; @@ -40,14 +36,17 @@ class DDC6613Test extends OrmFunctionalTestCase public function testFail() { - $user = new DDC6613User(); - $this->_em->persist($user); + $newUser = new DDC6613User(); + $this->_em->persist($newUser); $this->_em->flush(); $this->_em->clear(); - /** @var User $user */ - $user = $this->_em->find(User::class, 1); + /** @var DDC6613User $user */ + $user = $this->_em->find(DDC6613User::class, $newUser->id); + + self::assertInstanceOf(DDC6613User::class, $user); + $phone1 = new DDC6613Phone(); $phones = $user->phones; $user->phones->add($phone1); @@ -88,10 +87,10 @@ class DDC6613User * @GeneratedValue(strategy="NONE") * @Column(type="string") */ - private $id; + public $id; /** - * @ManyToMany(targetEntity="Phone", fetch="LAZY", cascade={"remove", "detach"}) + * @ManyToMany(targetEntity=DDC6613Phone::class, fetch="LAZY", cascade={"remove", "detach"}) */ public $phones; @@ -103,6 +102,7 @@ class DDC6613User } /** + * @Entity * @Table(name="ddc6613_phone") */ class DDC6613Phone From d7919678e5ceb063b96bd7b31be8a1e8ad034b51 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:34:35 +0200 Subject: [PATCH 07/23] #6613 #6614 remove superfluous mappings --- .../ORM/Functional/Ticket/DDC6613Test.php | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 5c3e0c039..26fe56b01 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -76,22 +76,13 @@ class DDC6613Test extends OrmFunctionalTestCase } } -/** - * @Entity - * @Table(name="ddc6613_user") - */ +/** @Entity */ class DDC6613User { - /** - * @Id - * @GeneratedValue(strategy="NONE") - * @Column(type="string") - */ + /** @Id @Column(type="string") */ public $id; - /** - * @ManyToMany(targetEntity=DDC6613Phone::class, fetch="LAZY", cascade={"remove", "detach"}) - */ + /** @ManyToMany(targetEntity=DDC6613Phone::class) */ public $phones; public function __construct() @@ -101,18 +92,11 @@ class DDC6613User } } -/** - * @Entity - * @Table(name="ddc6613_phone") - */ +/** @Entity */ class DDC6613Phone { - /** - * @Id - * @GeneratedValue(strategy="NONE") - * @Column(type="integer") - */ - public $id; + /** @Id @Column(type="integer") */ + private $id; public function __construct() { From b9ba4e3207a2e59b24003fa65bfbceba28243177 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:41:32 +0200 Subject: [PATCH 08/23] #6613 #6614 correcting column mapping (was `integer`, should be `string`), segregating phone creation away --- .../ORM/Functional/Ticket/DDC6613Test.php | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 26fe56b01..84f60243d 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -9,7 +9,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\DBAL\Schema\SchemaException; use Doctrine\ORM\PersistentCollection; use Doctrine\Tests\OrmFunctionalTestCase; @@ -23,46 +22,43 @@ class DDC6613Test extends OrmFunctionalTestCase { parent::setUp(); - try { - $this->setUpEntitySchema( - [ - DDC6613Phone::class, - DDC6613User::class, - ] - ); - } catch (SchemaException $e) { - } + $this->setUpEntitySchema([ + DDC6613Phone::class, + DDC6613User::class, + ]); } public function testFail() { $newUser = new DDC6613User(); + $this->_em->persist($newUser); $this->_em->flush(); - $this->_em->clear(); - /** @var DDC6613User $user */ - $user = $this->_em->find(DDC6613User::class, $newUser->id); + $phone1 = new DDC6613Phone(); + $phone2 = new DDC6613Phone(); + + $this->_em->persist($phone1); + $this->_em->persist($phone2); + $this->_em->flush(); + + /* @var DDC6613User $user */ + $user = $this->_em->find(DDC6613User::class, $newUser->id); self::assertInstanceOf(DDC6613User::class, $user); - $phone1 = new DDC6613Phone(); - $phones = $user->phones; - $user->phones->add($phone1); - $this->_em->persist($phone1); - $this->_em->flush(); - - $phone2 = new DDC6613Phone(); - $user->phones->add($phone2); - $this->_em->persist($phone2); - /* @var $phones PersistentCollection */ -// $phones = $user->phones; + $phones = $user->phones; self::assertInstanceOf(PersistentCollection::class, $phones); self::assertFalse($phones->isInitialized()); + $phones->add($phone1); + $this->_em->flush(); + + $phones->add($phone2); + $phones->initialize(); self::assertTrue($phones->isInitialized()); @@ -95,7 +91,7 @@ class DDC6613User /** @Entity */ class DDC6613Phone { - /** @Id @Column(type="integer") */ + /** @Id @Column(type="string") */ private $id; public function __construct() From 5a0d3e5fb8cd44becdaa9a164b86a9936be6e4f8 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:44:04 +0200 Subject: [PATCH 09/23] #6613 #6614 removing phone/user specifics, using ORM naming for associations --- .../ORM/Functional/Ticket/DDC6613Test.php | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 84f60243d..2456f1ed9 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -23,41 +23,41 @@ class DDC6613Test extends OrmFunctionalTestCase parent::setUp(); $this->setUpEntitySchema([ - DDC6613Phone::class, - DDC6613User::class, + DDC6613InverseSide::class, + DDC6613OwningSide::class, ]); } public function testFail() { - $newUser = new DDC6613User(); + $owningSide = new DDC6613OwningSide(); - $this->_em->persist($newUser); + $this->_em->persist($owningSide); $this->_em->flush(); $this->_em->clear(); - $phone1 = new DDC6613Phone(); - $phone2 = new DDC6613Phone(); + $item1 = new DDC6613InverseSide(); + $item2 = new DDC6613InverseSide(); - $this->_em->persist($phone1); - $this->_em->persist($phone2); + $this->_em->persist($item1); + $this->_em->persist($item2); $this->_em->flush(); - /* @var DDC6613User $user */ - $user = $this->_em->find(DDC6613User::class, $newUser->id); + /* @var DDC6613OwningSide $foundOwningSide */ + $foundOwningSide = $this->_em->find(DDC6613OwningSide::class, $owningSide->id); - self::assertInstanceOf(DDC6613User::class, $user); + self::assertInstanceOf(DDC6613OwningSide::class, $foundOwningSide); /* @var $phones PersistentCollection */ - $phones = $user->phones; + $phones = $foundOwningSide->phones; self::assertInstanceOf(PersistentCollection::class, $phones); self::assertFalse($phones->isInitialized()); - $phones->add($phone1); + $phones->add($item1); $this->_em->flush(); - $phones->add($phone2); + $phones->add($item2); $phones->initialize(); @@ -68,17 +68,17 @@ class DDC6613Test extends OrmFunctionalTestCase self::assertFalse($phones->isDirty()); self::assertTrue($phones->isInitialized()); - self::assertCount(2, $user->phones); + self::assertCount(2, $foundOwningSide->phones); } } /** @Entity */ -class DDC6613User +class DDC6613OwningSide { /** @Id @Column(type="string") */ public $id; - /** @ManyToMany(targetEntity=DDC6613Phone::class) */ + /** @ManyToMany(targetEntity=DDC6613InverseSide::class) */ public $phones; public function __construct() @@ -89,7 +89,7 @@ class DDC6613User } /** @Entity */ -class DDC6613Phone +class DDC6613InverseSide { /** @Id @Column(type="string") */ private $id; From 09189fc0214b1f1484ff48f616cf19a4c76bb65a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:44:28 +0200 Subject: [PATCH 10/23] #6613 #6614 removing IDE-generated header --- tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 2456f1ed9..35195f290 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -1,10 +1,4 @@ - * Date: 11.08.2017 - * Time: 12:28 - */ namespace Doctrine\Tests\ORM\Functional\Ticket; From 3155d970d38405b4e35ecd9232c2b7eb095ed890 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:46:11 +0200 Subject: [PATCH 11/23] #6613 #6614 adding assertions about collection initialization and dirty status --- .../Tests/ORM/Functional/Ticket/DDC6613Test.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 35195f290..519e88e88 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -47,15 +47,27 @@ class DDC6613Test extends OrmFunctionalTestCase self::assertInstanceOf(PersistentCollection::class, $phones); self::assertFalse($phones->isInitialized()); + self::assertFalse($phones->isDirty()); $phones->add($item1); + + self::assertFalse($phones->isInitialized()); + self::assertTrue($phones->isDirty()); + $this->_em->flush(); + self::assertFalse($phones->isInitialized()); + self::assertFalse($phones->isDirty()); + $phones->add($item2); + self::assertFalse($phones->isInitialized()); + self::assertTrue($phones->isDirty()); + $phones->initialize(); self::assertTrue($phones->isInitialized()); + self::assertFalse($phones->isDirty(), 'Possibly wrong assertion'); self::assertCount(2, $phones); $this->_em->flush(); From 49694dc335f8b0be22990a09c2e97f9359013120 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 14:47:27 +0200 Subject: [PATCH 12/23] #6613 #6614 after initialization, the collection should be dirty anyway --- tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php index 519e88e88..d95c8d8ff 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php @@ -67,7 +67,7 @@ class DDC6613Test extends OrmFunctionalTestCase $phones->initialize(); self::assertTrue($phones->isInitialized()); - self::assertFalse($phones->isDirty(), 'Possibly wrong assertion'); + self::assertTrue($phones->isDirty()); self::assertCount(2, $phones); $this->_em->flush(); From 5521d1f325ca157ed12e7730253267694a0cec03 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 15:13:39 +0200 Subject: [PATCH 13/23] #6613 #6614 ensuring that only newly added items that weren't loaded are restored in the dirty state of the collection --- lib/Doctrine/ORM/PersistentCollection.php | 37 +++++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index a4b579b7e..4a64c8fd6 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -19,7 +19,6 @@ namespace Doctrine\ORM; -use Closure; use Doctrine\Common\Collections\AbstractLazyCollection; use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\ArrayCollection; @@ -685,23 +684,41 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec protected function doInitialize() { // Has NEW objects added through add(). Remember them. - $newObjects = array(); + $newlyAddedDirtyObjects = array(); if ($this->isDirty) { - $newObjects = $this->collection->toArray(); + $newlyAddedDirtyObjects = $this->collection->toArray(); } $this->collection->clear(); $this->em->getUnitOfWork()->loadCollection($this); $this->takeSnapshot(); - // Reattach NEW objects added through add(), if any. - if ($newObjects) { - foreach ($newObjects as $obj) { - $this->collection->add($obj); - } - - $this->isDirty = true; + if ($newlyAddedDirtyObjects) { + $this->restoreNewObjectsInDirtyCollection($newlyAddedDirtyObjects); } } + + /** + * @param object[] $newObjects + * + * @return void + * + * Note: the only reason why this entire looping/complexity is performed via `spl_object_hash` + * is because we want to prevent using `array_udiff()`, which is likely to cause very + * high overhead (complexity of O(n^2)). `array_diff_key()` performs the operation in + * core, which is faster than using a callback for comparisons + */ + private function restoreNewObjectsInDirtyCollection(array $newObjects) + { + $loadedObjects = $this->collection->toArray(); + $newObjectsByOid = array_combine(array_map('spl_object_hash', $newObjects), $newObjects); + $loadedObjectsByOid = array_combine(array_map('spl_object_hash', $loadedObjects), $loadedObjects); + $newObjectsThatWereNotLoaded = array_diff_key($newObjectsByOid, $loadedObjectsByOid); + + // Reattach NEW objects added through add(), if any. + array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']); + + $this->isDirty = true; + } } From 9545bf9d8cc6b3022c8ab0868284493bf22f6692 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 15:14:42 +0200 Subject: [PATCH 14/23] #6613 #6614 correcting broken test that isn't using objects against a `PersistentCollection` --- tests/Doctrine/Tests/ORM/PersistentCollectionTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 190fe2ef1..ac4597b15 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -90,10 +90,12 @@ class PersistentCollectionTest extends OrmTestCase { $this->setUpPersistentCollection(); - $this->collection->add('dummy'); + $dummy = new \stdClass(); + + $this->collection->add($dummy); $this->assertEquals([0], array_keys($this->collection->toArray())); - $this->collection->removeElement('dummy'); + $this->collection->removeElement($dummy); $this->assertEquals([], array_keys($this->collection->toArray())); } @@ -104,7 +106,7 @@ class PersistentCollectionTest extends OrmTestCase { $this->setUpPersistentCollection(); - $this->collection->add('dummy'); + $this->collection->add(new \stdClass()); $this->collection->clear(); $this->assertEquals([], array_keys($this->collection->toArray())); } From 59c55745541e6eeb1d2d590674281226c1307d15 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 15:15:57 +0200 Subject: [PATCH 15/23] #6613 #6614 correcting broken test that isn't using objects against a `PersistentCollection` --- tests/Doctrine/Tests/ORM/PersistentCollectionTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index ac4597b15..3511272a2 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -118,10 +118,12 @@ class PersistentCollectionTest extends OrmTestCase { $this->setUpPersistentCollection(); - $this->collection->add('dummy'); - $this->collection->removeElement('dummy'); + $dummy = new \stdClass(); + + $this->collection->add($dummy); + $this->collection->removeElement($dummy); $this->collection->clear(); - $this->collection->add('dummy'); + $this->collection->add($dummy); $this->assertEquals([0], array_keys($this->collection->toArray())); } } From bdae3627773f202bf2bea19158b3399f16df10c2 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 18:58:05 +0200 Subject: [PATCH 16/23] #6613 #6614 #6616 moved integration test basics to a unit test that verifies basic dirty collection initialization semantics --- .../Tests/ORM/PersistentCollectionTest.php | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 3511272a2..3b699e4ab 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -3,7 +3,9 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\PersistentCollection; +use Doctrine\ORM\UnitOfWork; use Doctrine\Tests\Mocks\ConnectionMock; use Doctrine\Tests\Mocks\DriverMock; use Doctrine\Tests\Mocks\EntityManagerMock; @@ -23,7 +25,7 @@ class PersistentCollectionTest extends OrmTestCase protected $collection; /** - * @var \Doctrine\ORM\EntityManagerInterface + * @var EntityManagerMock */ private $_emMock; @@ -126,4 +128,41 @@ class PersistentCollectionTest extends OrmTestCase $this->collection->add($dummy); $this->assertEquals([0], array_keys($this->collection->toArray())); } + + /** + * @group 6613 + * @group 6614 + * @group 6616 + */ + public function testWillKeepNewItemsAfterInitialization() + { + /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */ + $unitOfWork = $this->createMock(UnitOfWork::class); + + $this->_emMock->setUnitOfWork($unitOfWork); + + $this->setUpPersistentCollection(); + + $newElement = new \stdClass(); + $persistedElement = new \stdClass(); + + $this->collection->add($newElement); + + self::assertFalse($this->collection->isInitialized()); + self::assertTrue($this->collection->isDirty()); + + $unitOfWork + ->expects(self::once()) + ->method('loadCollection') + ->with($this->collection) + ->willReturnCallback(function (PersistentCollection $persistentCollection) use ($persistedElement) { + $persistentCollection->unwrap()->add($persistedElement); + }); + + $this->collection->initialize(); + + self::assertSame([$persistedElement, $newElement], $this->collection->toArray()); + self::assertTrue($this->collection->isInitialized()); + self::assertTrue($this->collection->isDirty()); + } } From d6bcb5b1f8090cba6cc141104861fa013d5e772a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 19:02:39 +0200 Subject: [PATCH 17/23] #6613 #6614 #6616 initializing a dirty collection that has new items that are also coming from initialization data de-duplicates new and persisted items --- .../Tests/ORM/PersistentCollectionTest.php | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 3b699e4ab..40a360094 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -134,7 +134,7 @@ class PersistentCollectionTest extends OrmTestCase * @group 6614 * @group 6616 */ - public function testWillKeepNewItemsAfterInitialization() + public function testWillKeepNewItemsInDirtyCollectionAfterInitialization() { /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */ $unitOfWork = $this->createMock(UnitOfWork::class); @@ -165,4 +165,50 @@ class PersistentCollectionTest extends OrmTestCase self::assertTrue($this->collection->isInitialized()); self::assertTrue($this->collection->isDirty()); } + + /** + * @group 6613 + * @group 6614 + * @group 6616 + */ + public function testWillDeDuplicateNewItemsThatWerePreviouslyPersistedInDirtyCollectionAfterInitialization() + { + /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */ + $unitOfWork = $this->createMock(UnitOfWork::class); + + $this->_emMock->setUnitOfWork($unitOfWork); + + $this->setUpPersistentCollection(); + + $newElement = new \stdClass(); + $newElementThatIsAlsoPersisted = new \stdClass(); + $persistedElement = new \stdClass(); + + $this->collection->add($newElementThatIsAlsoPersisted); + $this->collection->add($newElement); + + self::assertFalse($this->collection->isInitialized()); + self::assertTrue($this->collection->isDirty()); + + $unitOfWork + ->expects(self::once()) + ->method('loadCollection') + ->with($this->collection) + ->willReturnCallback(function (PersistentCollection $persistentCollection) use ( + $persistedElement, + $newElementThatIsAlsoPersisted + ) { + $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted); + $persistentCollection->unwrap()->add($persistedElement); + }); + + $this->collection->initialize(); + + self::assertSame( + [$newElementThatIsAlsoPersisted, $persistedElement, $newElement], + $this->collection->toArray() + ); + self::assertTrue($this->collection->isInitialized()); + self::assertTrue($this->collection->isDirty()); + } } From 61cb03bf3057e55845b40d2c6b869e8ee3662754 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 19:08:24 +0200 Subject: [PATCH 18/23] #6613 #6614 #6616 removing repeated `PersistentCollectionTest` chunks of code --- .../Tests/ORM/PersistentCollectionTest.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 40a360094..3b301fcf0 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -34,6 +34,8 @@ class PersistentCollectionTest extends OrmTestCase parent::setUp(); $this->_emMock = EntityManagerMock::create(new ConnectionMock([], new DriverMock())); + + $this->setUpPersistentCollection(); } /** @@ -60,7 +62,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testCurrentInitializesCollection() { - $this->setUpPersistentCollection(); $this->collection->current(); $this->assertTrue($this->collection->isInitialized()); } @@ -70,7 +71,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testKeyInitializesCollection() { - $this->setUpPersistentCollection(); $this->collection->key(); $this->assertTrue($this->collection->isInitialized()); } @@ -80,7 +80,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testNextInitializesCollection() { - $this->setUpPersistentCollection(); $this->collection->next(); $this->assertTrue($this->collection->isInitialized()); } @@ -90,8 +89,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testRemovingElementsAlsoRemovesKeys() { - $this->setUpPersistentCollection(); - $dummy = new \stdClass(); $this->collection->add($dummy); @@ -106,8 +103,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testClearWillAlsoClearKeys() { - $this->setUpPersistentCollection(); - $this->collection->add(new \stdClass()); $this->collection->clear(); $this->assertEquals([], array_keys($this->collection->toArray())); @@ -118,8 +113,6 @@ class PersistentCollectionTest extends OrmTestCase */ public function testClearWillAlsoResetKeyPositions() { - $this->setUpPersistentCollection(); - $dummy = new \stdClass(); $this->collection->add($dummy); @@ -141,8 +134,6 @@ class PersistentCollectionTest extends OrmTestCase $this->_emMock->setUnitOfWork($unitOfWork); - $this->setUpPersistentCollection(); - $newElement = new \stdClass(); $persistedElement = new \stdClass(); @@ -178,8 +169,6 @@ class PersistentCollectionTest extends OrmTestCase $this->_emMock->setUnitOfWork($unitOfWork); - $this->setUpPersistentCollection(); - $newElement = new \stdClass(); $newElementThatIsAlsoPersisted = new \stdClass(); $persistedElement = new \stdClass(); From abb429a0c96d6f5838eb49f5359176fb44d705a1 Mon Sep 17 00:00:00 2001 From: Andreas Braun Date: Fri, 11 Aug 2017 20:37:23 +0200 Subject: [PATCH 19/23] Add failing test for dirty flag --- .../Tests/ORM/PersistentCollectionTest.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index 3b301fcf0..e18f3add8 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -200,4 +200,46 @@ class PersistentCollectionTest extends OrmTestCase self::assertTrue($this->collection->isInitialized()); self::assertTrue($this->collection->isDirty()); } + + /** + * @group 6613 + * @group 6614 + * @group 6616 + */ + public function testWillNotMarkCollectionAsDirtyAfterInitializationIfNoElementsWereAdded() + { + /* @var $unitOfWork UnitOfWork|\PHPUnit_Framework_MockObject_MockObject */ + $unitOfWork = $this->createMock(UnitOfWork::class); + + $this->_emMock->setUnitOfWork($unitOfWork); + + $newElementThatIsAlsoPersisted = new \stdClass(); + $persistedElement = new \stdClass(); + + $this->collection->add($newElementThatIsAlsoPersisted); + + self::assertFalse($this->collection->isInitialized()); + self::assertTrue($this->collection->isDirty()); + + $unitOfWork + ->expects(self::once()) + ->method('loadCollection') + ->with($this->collection) + ->willReturnCallback(function (PersistentCollection $persistentCollection) use ( + $persistedElement, + $newElementThatIsAlsoPersisted + ) { + $persistentCollection->unwrap()->add($newElementThatIsAlsoPersisted); + $persistentCollection->unwrap()->add($persistedElement); + }); + + $this->collection->initialize(); + + self::assertSame( + [$newElementThatIsAlsoPersisted, $persistedElement], + $this->collection->toArray() + ); + self::assertTrue($this->collection->isInitialized()); + self::assertFalse($this->collection->isDirty()); + } } From 15731c7bde96bfc77e9d761ce1ee80269cbb5ad6 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 21:09:34 +0200 Subject: [PATCH 20/23] #6613 #6614 #6616 ensuring that the collection is marked as non-dirty if all new items are contained in the initialized ones --- lib/Doctrine/ORM/PersistentCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 4a64c8fd6..0b57302c0 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -719,6 +719,6 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec // Reattach NEW objects added through add(), if any. array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']); - $this->isDirty = true; + $this->isDirty = (bool) $newObjectsThatWereNotLoaded; } } From ab63628960999674a84dbf9d6fda687acb128a1d Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 21:11:31 +0200 Subject: [PATCH 21/23] #6613 #6614 #6616 removing DDC6613 test, which was fully ported to unit tests --- .../ORM/Functional/Ticket/DDC6613Test.php | 107 ------------------ 1 file changed, 107 deletions(-) delete mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php deleted file mode 100644 index d95c8d8ff..000000000 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC6613Test.php +++ /dev/null @@ -1,107 +0,0 @@ -setUpEntitySchema([ - DDC6613InverseSide::class, - DDC6613OwningSide::class, - ]); - } - - public function testFail() - { - $owningSide = new DDC6613OwningSide(); - - $this->_em->persist($owningSide); - $this->_em->flush(); - $this->_em->clear(); - - $item1 = new DDC6613InverseSide(); - $item2 = new DDC6613InverseSide(); - - $this->_em->persist($item1); - $this->_em->persist($item2); - $this->_em->flush(); - - /* @var DDC6613OwningSide $foundOwningSide */ - $foundOwningSide = $this->_em->find(DDC6613OwningSide::class, $owningSide->id); - - self::assertInstanceOf(DDC6613OwningSide::class, $foundOwningSide); - - /* @var $phones PersistentCollection */ - $phones = $foundOwningSide->phones; - - self::assertInstanceOf(PersistentCollection::class, $phones); - self::assertFalse($phones->isInitialized()); - self::assertFalse($phones->isDirty()); - - $phones->add($item1); - - self::assertFalse($phones->isInitialized()); - self::assertTrue($phones->isDirty()); - - $this->_em->flush(); - - self::assertFalse($phones->isInitialized()); - self::assertFalse($phones->isDirty()); - - $phones->add($item2); - - self::assertFalse($phones->isInitialized()); - self::assertTrue($phones->isDirty()); - - $phones->initialize(); - - self::assertTrue($phones->isInitialized()); - self::assertTrue($phones->isDirty()); - self::assertCount(2, $phones); - - $this->_em->flush(); - - self::assertFalse($phones->isDirty()); - self::assertTrue($phones->isInitialized()); - self::assertCount(2, $foundOwningSide->phones); - } -} - -/** @Entity */ -class DDC6613OwningSide -{ - /** @Id @Column(type="string") */ - public $id; - - /** @ManyToMany(targetEntity=DDC6613InverseSide::class) */ - public $phones; - - public function __construct() - { - $this->id = uniqid('user', true); - $this->phones = new ArrayCollection(); - } -} - -/** @Entity */ -class DDC6613InverseSide -{ - /** @Id @Column(type="string") */ - private $id; - - public function __construct() - { - $this->id = uniqid('phone', true); - } -} \ No newline at end of file From 5cacb6e14f371c7e4054dd5a451ad7dd14b42935 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 21:14:05 +0200 Subject: [PATCH 22/23] #6613 #6614 #6616 minor performance optimisations around the new `restoreNewObjectsInDirtyCollection` implementation --- lib/Doctrine/ORM/PersistentCollection.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/Doctrine/ORM/PersistentCollection.php b/lib/Doctrine/ORM/PersistentCollection.php index 0b57302c0..48daa4dc6 100644 --- a/lib/Doctrine/ORM/PersistentCollection.php +++ b/lib/Doctrine/ORM/PersistentCollection.php @@ -712,13 +712,15 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec private function restoreNewObjectsInDirtyCollection(array $newObjects) { $loadedObjects = $this->collection->toArray(); - $newObjectsByOid = array_combine(array_map('spl_object_hash', $newObjects), $newObjects); - $loadedObjectsByOid = array_combine(array_map('spl_object_hash', $loadedObjects), $loadedObjects); - $newObjectsThatWereNotLoaded = array_diff_key($newObjectsByOid, $loadedObjectsByOid); + $newObjectsByOid = \array_combine(\array_map('spl_object_hash', $newObjects), $newObjects); + $loadedObjectsByOid = \array_combine(\array_map('spl_object_hash', $loadedObjects), $loadedObjects); + $newObjectsThatWereNotLoaded = \array_diff_key($newObjectsByOid, $loadedObjectsByOid); - // Reattach NEW objects added through add(), if any. - array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']); + if ($newObjectsThatWereNotLoaded) { + // Reattach NEW objects added through add(), if any. + \array_walk($newObjectsThatWereNotLoaded, [$this->collection, 'add']); - $this->isDirty = (bool) $newObjectsThatWereNotLoaded; + $this->isDirty = true; + } } } From 96c6f4cf1d48f83886998df28167c6198c66dc22 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 11 Aug 2017 21:25:10 +0200 Subject: [PATCH 23/23] #6613 #6614 #6616 removed unused import --- tests/Doctrine/Tests/ORM/PersistentCollectionTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php index e18f3add8..2ca179ef9 100644 --- a/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/PersistentCollectionTest.php @@ -3,7 +3,6 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Collection; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\UnitOfWork; use Doctrine\Tests\Mocks\ConnectionMock;