From ee246af7e3cafcfd1e9bff4def8831a53786e920 Mon Sep 17 00:00:00 2001 From: Andrea Sprega Date: Fri, 24 Oct 2014 23:10:37 +0200 Subject: [PATCH 01/14] [DDC-3343] Failing test case --- .../ORM/Functional/Ticket/DDC3343Test.php | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php new file mode 100644 index 000000000..c8a1f7359 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -0,0 +1,92 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3343User'), + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3343Group'), + )); + + // Save a group and an associated user (in an extra lazy association) + $group = new DDC3343Group(); + $user = new DDC3343User(); + + $group->users->add($user); + + $this->_em->persist($group); + $this->_em->persist($user); + $this->_em->flush(); + + // Fetch the group and the user again and remove the user from the collection. + $this->_em->clear(); + + $group = $this->_em->find(__NAMESPACE__ . '\DDC3343Group', $group->id); + $user = $this->_em->find(__NAMESPACE__ . '\DDC3343User', $user->id); + + $group->users->removeElement($user); + + $this->_em->persist($group); + $this->_em->flush(); + + // Even if the collection is extra lazy, the user should not have been deleted. + $this->_em->clear(); + + $user = $this->_em->find(__NAMESPACE__ . '\DDC3343User', $user->id); + $this->assertNotNull($user); + } +} + +/** + * @Entity + */ +class DDC3343User +{ + /** + * @Id + * @GeneratedValue + * @Column(type="integer") + */ + public $id; + + /** + * @ManyToOne(targetEntity="DDC3343Group", inversedBy="users") + */ + protected $group; +} + +/** + * @Entity + */ +class DDC3343Group +{ + /** + * @Id + * @GeneratedValue + * @Column(type="integer") + */ + public $id; + + /** + * @OneToMany(targetEntity="DDC3343User", mappedBy="group", fetch="EXTRA_LAZY") + */ + public $users; + + public function __construct() + { + $this->users = new ArrayCollection(); + } +} From a88550a70c0001ab4def72aa5f19122d33ca4cee Mon Sep 17 00:00:00 2001 From: Andrea Sprega Date: Sat, 25 Oct 2014 00:02:57 +0200 Subject: [PATCH 02/14] [DDC-3343] Failing test case (updated) --- tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php index c8a1f7359..c6db00bef 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -39,14 +39,11 @@ class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase $group->users->removeElement($user); - $this->_em->persist($group); - $this->_em->flush(); - - // Even if the collection is extra lazy, the user should not have been deleted. + // Even though the collection is extra lazy, the user should not have been deleted. $this->_em->clear(); $user = $this->_em->find(__NAMESPACE__ . '\DDC3343User', $user->id); - $this->assertNotNull($user); + $this->assertInstanceOf(__NAMESPACE__ . '\DDC3343User', $user); } } From ff0168834ea84467b79f57f22d6e4d3d5e2e28b0 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:40:48 +0100 Subject: [PATCH 03/14] Conflicts: lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php From 24ebfb69cb7040bbb72c9bc0e924054f85347798 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:41:20 +0100 Subject: [PATCH 04/14] #1169 DDC-3343 - minor refactoring: constant over string reference --- .../ORM/Functional/Ticket/DDC3343Test.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php index c6db00bef..4537c589f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -17,8 +17,8 @@ class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase public function testEntityNotDeletedWhenRemovedFromExtraLazyAssociation() { $this->_schemaTool->createSchema(array( - $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3343User'), - $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3343Group'), + $this->_em->getClassMetadata(DDC3343User::CLASSNAME), + $this->_em->getClassMetadata(DDC3343Group::CLASSNAME), )); // Save a group and an associated user (in an extra lazy association) @@ -34,16 +34,19 @@ class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase // Fetch the group and the user again and remove the user from the collection. $this->_em->clear(); - $group = $this->_em->find(__NAMESPACE__ . '\DDC3343Group', $group->id); - $user = $this->_em->find(__NAMESPACE__ . '\DDC3343User', $user->id); + $group = $this->_em->find(DDC3343Group::CLASSNAME, $group->id); + $user = $this->_em->find(DDC3343User::CLASSNAME, $user->id); $group->users->removeElement($user); // Even though the collection is extra lazy, the user should not have been deleted. $this->_em->clear(); - $user = $this->_em->find(__NAMESPACE__ . '\DDC3343User', $user->id); - $this->assertInstanceOf(__NAMESPACE__ . '\DDC3343User', $user); + /* @var $user DDC3343User */ + $user = $this->_em->find(DDC3343User::CLASSNAME, $user->id); + $this->assertInstanceOf(DDC3343User::CLASSNAME, $user); + + $this->assertNull($user->group); } } @@ -52,6 +55,8 @@ class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase */ class DDC3343User { + const CLASSNAME = __CLASS__; + /** * @Id * @GeneratedValue @@ -62,7 +67,7 @@ class DDC3343User /** * @ManyToOne(targetEntity="DDC3343Group", inversedBy="users") */ - protected $group; + public $group; } /** @@ -70,6 +75,8 @@ class DDC3343User */ class DDC3343Group { + const CLASSNAME = __CLASS__; + /** * @Id * @GeneratedValue From 7292920b15d8a4ea7cf4d3a4b31bb2b46c850cd1 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:54:03 +0100 Subject: [PATCH 05/14] #1169 DDC-3343 - refactoring test to use pre-existing test models --- tests/Doctrine/Tests/Models/Tweet/Tweet.php | 34 +++++++++++++++++ tests/Doctrine/Tests/Models/Tweet/User.php | 42 +++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 tests/Doctrine/Tests/Models/Tweet/Tweet.php create mode 100644 tests/Doctrine/Tests/Models/Tweet/User.php diff --git a/tests/Doctrine/Tests/Models/Tweet/Tweet.php b/tests/Doctrine/Tests/Models/Tweet/Tweet.php new file mode 100644 index 000000000..8a315df9e --- /dev/null +++ b/tests/Doctrine/Tests/Models/Tweet/Tweet.php @@ -0,0 +1,34 @@ +author = $user; + } +} diff --git a/tests/Doctrine/Tests/Models/Tweet/User.php b/tests/Doctrine/Tests/Models/Tweet/User.php new file mode 100644 index 000000000..4722e6317 --- /dev/null +++ b/tests/Doctrine/Tests/Models/Tweet/User.php @@ -0,0 +1,42 @@ +tweets = new ArrayCollection(); + } + + public function addTweet(Tweet $tweet) + { + $tweet->setAuthor($this); + $this->tweets->add($tweet); + } +} From 193ec5160786a663a2cb4b6971869330fc26acfc Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:54:17 +0100 Subject: [PATCH 06/14] #1169 DDC-3343 - refactoring test to use pre-existing test models --- .../ORM/Functional/Ticket/DDC3343Test.php | 96 +++++++------------ 1 file changed, 32 insertions(+), 64 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php index 4537c589f..9257883fd 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -8,89 +8,57 @@ use Doctrine\ORM\Mapping\GeneratedValue; use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\ManyToOne; use Doctrine\ORM\Mapping\OneToMany; +use Doctrine\Tests\Models\Tweet\Tweet; +use Doctrine\Tests\Models\Tweet\User; /** * @group DDC-3343 */ class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase { + /** + * {@inheritDoc} + */ + protected function setUp() + { + $this->useModelSet('tweet'); + + parent::setUp(); + } + public function testEntityNotDeletedWhenRemovedFromExtraLazyAssociation() { - $this->_schemaTool->createSchema(array( - $this->_em->getClassMetadata(DDC3343User::CLASSNAME), - $this->_em->getClassMetadata(DDC3343Group::CLASSNAME), - )); + $user = new User(); + $tweet = new Tweet(); - // Save a group and an associated user (in an extra lazy association) - $group = new DDC3343Group(); - $user = new DDC3343User(); + $user->name = 'ocramius'; + $tweet->content = 'The cat is on the table'; - $group->users->add($user); + $user->addTweet($tweet); - $this->_em->persist($group); $this->_em->persist($user); + $this->_em->persist($tweet); $this->_em->flush(); - - // Fetch the group and the user again and remove the user from the collection. $this->_em->clear(); - $group = $this->_em->find(DDC3343Group::CLASSNAME, $group->id); - $user = $this->_em->find(DDC3343User::CLASSNAME, $user->id); + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $user->id); + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - $group->users->removeElement($user); + $user->tweets->removeElement($tweet); + + $this->assertCount(0, $user->tweets); - // Even though the collection is extra lazy, the user should not have been deleted. $this->_em->clear(); - /* @var $user DDC3343User */ - $user = $this->_em->find(DDC3343User::CLASSNAME, $user->id); - $this->assertInstanceOf(DDC3343User::CLASSNAME, $user); + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); - $this->assertNull($user->group); - } -} - -/** - * @Entity - */ -class DDC3343User -{ - const CLASSNAME = __CLASS__; - - /** - * @Id - * @GeneratedValue - * @Column(type="integer") - */ - public $id; - - /** - * @ManyToOne(targetEntity="DDC3343Group", inversedBy="users") - */ - public $group; -} - -/** - * @Entity - */ -class DDC3343Group -{ - const CLASSNAME = __CLASS__; - - /** - * @Id - * @GeneratedValue - * @Column(type="integer") - */ - public $id; - - /** - * @OneToMany(targetEntity="DDC3343User", mappedBy="group", fetch="EXTRA_LAZY") - */ - public $users; - - public function __construct() - { - $this->users = new ArrayCollection(); + $this->assertNull($tweet->author); } } From 41258deed7c767ace12cc581c5ecd8824914cfbf Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:54:32 +0100 Subject: [PATCH 07/14] #1169 DDC-3343 - optimized imports --- tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php index 9257883fd..1831b6bce 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -2,12 +2,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; -use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\ORM\Mapping\Column; -use Doctrine\ORM\Mapping\GeneratedValue; -use Doctrine\ORM\Mapping\Id; -use Doctrine\ORM\Mapping\ManyToOne; -use Doctrine\ORM\Mapping\OneToMany; use Doctrine\Tests\Models\Tweet\Tweet; use Doctrine\Tests\Models\Tweet\User; From d69fd914546501c903782f161ffa75f41b947a99 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:54:58 +0100 Subject: [PATCH 08/14] #1169 DDC-3343 - importing used classe --- tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php index 1831b6bce..1dd750079 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php @@ -4,11 +4,12 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\Tests\Models\Tweet\Tweet; use Doctrine\Tests\Models\Tweet\User; +use Doctrine\Tests\OrmFunctionalTestCase; /** * @group DDC-3343 */ -class DDC3343Test extends \Doctrine\Tests\OrmFunctionalTestCase +class DDC3343Test extends OrmFunctionalTestCase { /** * {@inheritDoc} From cfed92a5cf73c91ca830314b8fc8c87fcc66c477 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:58:57 +0100 Subject: [PATCH 09/14] #1169 DDC-3343 - integrating tests into the existing test suite Conflicts: tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php --- .../OneToManyExtraLazyTest.php | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php new file mode 100644 index 000000000..383940f51 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php @@ -0,0 +1,147 @@ +useModelSet('tweet'); + $this->useModelSet('vct_onetomany_extralazy'); + + parent::setUp(); + + $inversed = new Entity\InversedOneToManyExtraLazyEntity(); + $inversed->id1 = 'abc'; + + $owning1 = new Entity\OwningManyToOneExtraLazyEntity(); + $owning1->id2 = 'def'; + + $owning2 = new Entity\OwningManyToOneExtraLazyEntity(); + $owning2->id2 = 'ghi'; + + $owning3 = new Entity\OwningManyToOneExtraLazyEntity(); + $owning3->id2 = 'jkl'; + + $inversed->associatedEntities->add($owning1); + $owning1->associatedEntity = $inversed; + $inversed->associatedEntities->add($owning2); + $owning2->associatedEntity = $inversed; + $inversed->associatedEntities->add($owning3); + $owning3->associatedEntity = $inversed; + + $this->_em->persist($inversed); + $this->_em->persist($owning1); + $this->_em->persist($owning2); + $this->_em->persist($owning3); + + $this->_em->flush(); + $this->_em->clear(); + } + + public static function tearDownAfterClass() + { + $conn = static::$_sharedConn; + + $conn->executeUpdate('DROP TABLE vct_owning_manytoone_extralazy'); + $conn->executeUpdate('DROP TABLE vct_inversed_onetomany_extralazy'); + } + + public function testThatExtraLazyCollectionIsCounted() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', + 'abc' + ); + + $this->assertEquals(3, $inversed->associatedEntities->count()); + } + + public function testThatExtraLazyCollectionContainsAnEntity() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', + 'abc' + ); + + $owning = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneExtraLazyEntity', + 'def' + ); + + $this->assertTrue($inversed->associatedEntities->contains($owning)); + } + + public function testThatExtraLazyCollectionContainsAnIndexbyKey() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', + 'abc' + ); + + $this->assertTrue($inversed->associatedEntities->containsKey('def')); + } + + public function testThatASliceOfTheExtraLazyCollectionIsLoaded() + { + $inversed = $this->_em->find( + 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', + 'abc' + ); + + $this->assertCount(2, $inversed->associatedEntities->slice(0, 2)); + } + + /** + * @group DDC-3343 + */ + public function testEntityNotDeletedWhenRemovedFromExtraLazyAssociation() + { + $user = new User(); + $tweet = new Tweet(); + + $user->name = 'ocramius'; + $tweet->content = 'The cat is on the table'; + + $user->addTweet($tweet); + + $this->_em->persist($user); + $this->_em->persist($tweet); + $this->_em->flush(); + $this->_em->clear(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $user->id); + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); + + $user->tweets->removeElement($tweet); + + $this->assertCount(0, $user->tweets); + + $this->_em->clear(); + + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); + + $this->assertNull($tweet->author); + } +} From 50ac97e72d4dc98d08c8566a3e0dda76fc73feb3 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 11:59:21 +0100 Subject: [PATCH 10/14] #1169 DDC-3343 - removing duplicate test --- .../ORM/Functional/Ticket/DDC3343Test.php | 59 ------------------- 1 file changed, 59 deletions(-) delete mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php deleted file mode 100644 index 1dd750079..000000000 --- a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3343Test.php +++ /dev/null @@ -1,59 +0,0 @@ -useModelSet('tweet'); - - parent::setUp(); - } - - public function testEntityNotDeletedWhenRemovedFromExtraLazyAssociation() - { - $user = new User(); - $tweet = new Tweet(); - - $user->name = 'ocramius'; - $tweet->content = 'The cat is on the table'; - - $user->addTweet($tweet); - - $this->_em->persist($user); - $this->_em->persist($tweet); - $this->_em->flush(); - $this->_em->clear(); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $user->id); - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - - $user->tweets->removeElement($tweet); - - $this->assertCount(0, $user->tweets); - - $this->_em->clear(); - - /* @var $tweet Tweet */ - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - $this->assertInstanceOf( - Tweet::CLASSNAME, - $tweet, - 'Even though the collection is extra lazy, the tweet should not have been deleted' - ); - - $this->assertNull($tweet->author); - } -} From 52fbe35bc73f93ecf5520a236defacc3df05a612 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 12:20:33 +0100 Subject: [PATCH 11/14] #1169 DDC-3343 - correcting query count assertions on extra-lazy specific tests (some DELETE operations became UPDATE operations) Conflicts: lib/Doctrine/ORM/Persisters/Collection/OneToManyPersister.php tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php --- .../Functional/ExtraLazyCollectionTest.php | 89 ++++++++++++++++++- 1 file changed, 87 insertions(+), 2 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index eb4dbe4d8..6005dda6c 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -363,7 +363,8 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $user->articles->removeElement($article); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); - $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount()); + // NOTE: +2 queries because CmsArticle is a versioned entity, and that needs to be handled accordingly + $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount()); // Test One to Many removal with Entity state as new $article = new \Doctrine\Tests\Models\CMS\CmsArticle(); @@ -384,7 +385,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $user->articles->removeElement($article); - $this->assertEquals($queryCount + 1, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed."); + $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a persisted entity will not cause queries when the owning side doesn't actually change."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); // Test One to Many removal with Entity state as managed @@ -401,6 +402,90 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed."); } + /** + * @group DDC-2504 + */ + public function testRemovalOfManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() + { + $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); + $childClass = $this->_em->find(DDC2504ChildClass::CLASSNAME, $this->ddc2504ChildClassId); + + $queryCount = $this->getCurrentQueryCount(); + + $otherClass->childClasses->removeElement($childClass); + + $this->assertFalse($otherClass->childClasses->isInitialized(), 'Collection is not initialized.'); + + $this->assertEquals( + $queryCount + 1, + $this->getCurrentQueryCount(), + 'The owning side of the association is updated' + ); + + $this->assertFalse($otherClass->childClasses->contains($childClass)); + } + + /** + * @group DDC-2504 + */ + public function testRemovalOfNonManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() + { + $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); + $queryCount = $this->getCurrentQueryCount(); + + $otherClass->childClasses->removeElement(new DDC2504ChildClass()); + + $this->assertEquals( + $queryCount, + $this->getCurrentQueryCount(), + 'Removing an unmanaged entity should cause no query to be executed.' + ); + } + + /** + * @group DDC-2504 + */ + public function testRemovalOfNewElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() + { + $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); + $childClass = new DDC2504ChildClass(); + + $this->_em->persist($childClass); + + $queryCount = $this->getCurrentQueryCount(); + + $otherClass->childClasses->removeElement($childClass); + + $this->assertEquals( + $queryCount, + $this->getCurrentQueryCount(), + 'Removing a new entity should cause no query to be executed.' + ); + } + + /** + * @group DDC-2504 + */ + public function testRemovalOfNewManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() + { + $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); + $childClass = new DDC2504ChildClass(); + + $this->_em->persist($childClass); + $this->_em->flush(); + + $queryCount = $this->getCurrentQueryCount(); + + $otherClass->childClasses->removeElement($childClass); + + $this->assertEquals( + $queryCount, + $this->getCurrentQueryCount(), + 'No queries are executed, as the owning side of the association is not actually updated.' + ); + $this->assertFalse($otherClass->childClasses->isInitialized(), 'Collection is not initialized.'); + } + /** * */ From daca81861c694a8cbf1fb6696cdad0df3de1bed0 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 12:21:21 +0100 Subject: [PATCH 12/14] #1169 DDC-3343 - additional test cases: removing proxies from an extra-lazy collection still updates the owning side values --- .../OneToManyExtraLazyTest.php | 98 +++++++++++++++---- 1 file changed, 78 insertions(+), 20 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php index 383940f51..c323a44d8 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php @@ -109,7 +109,83 @@ class OneToManyExtraLazyTest extends OrmFunctionalTestCase /** * @group DDC-3343 */ - public function testEntityNotDeletedWhenRemovedFromExtraLazyAssociation() + public function testRemovesManagedElementFromOneToManyExtraLazyCollection() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->tweets); + } + + /** + * @group DDC-3343 + */ + public function testRemovesManagedElementFromOneToManyExtraLazyCollectionWithoutDeletingTheTargetEntityEntry() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweetId); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); + + $this->assertNull($tweet->author, 'Tweet author link has been removed'); + } + + /** + * @group DDC-3343 + */ + public function testRemovingManagedLazyProxyFromExtraLazyOneToManyDoesRemoveTheAssociationButNotTheEntity() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + $tweet = $this->_em->getReference(Tweet::CLASSNAME, $tweetId); + + $user->tweets->removeElement($this->_em->getReference(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); + + $this->assertNull($tweet->author); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->tweets); + } + + /** + * @return int[] ordered tuple: user id and tweet id + */ + private function loadTweetFixture() { $user = new User(); $tweet = new Tweet(); @@ -124,24 +200,6 @@ class OneToManyExtraLazyTest extends OrmFunctionalTestCase $this->_em->flush(); $this->_em->clear(); - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $user->id); - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - - $user->tweets->removeElement($tweet); - - $this->assertCount(0, $user->tweets); - - $this->_em->clear(); - - /* @var $tweet Tweet */ - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - $this->assertInstanceOf( - Tweet::CLASSNAME, - $tweet, - 'Even though the collection is extra lazy, the tweet should not have been deleted' - ); - - $this->assertNull($tweet->author); + return array($user->id, $tweet->id); } } From c4b59b4eb046e4d472cacb87c5801ba661fc934a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 12:50:10 +0100 Subject: [PATCH 13/14] #1169 DDC-3343 - adapting patch to 2.4 branch --- .../ORM/Persisters/OneToManyPersister.php | 20 +++-- .../Functional/ExtraLazyCollectionTest.php | 84 ------------------- .../OneToManyExtraLazyTest.php | 82 ------------------ .../Doctrine/Tests/OrmFunctionalTestCase.php | 8 ++ 4 files changed, 23 insertions(+), 171 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php index 2915fd2ed..cf39436d4 100644 --- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -19,6 +19,7 @@ namespace Doctrine\ORM\Persisters; +use Doctrine\Common\Proxy\Proxy; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\UnitOfWork; @@ -237,11 +238,20 @@ class OneToManyPersister extends AbstractCollectionPersister return false; } - $mapping = $coll->getMapping(); - $class = $this->em->getClassMetadata($mapping['targetEntity']); - $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform) - . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; + $mapping = $coll->getMapping(); + $persister = $this->uow->getEntityPersister($mapping['targetEntity']); + $targetMetadata = $this->em->getClassMetadata($mapping['targetEntity']); - return (bool) $this->conn->executeUpdate($sql, $this->getDeleteRowSQLParameters($coll, $element)); + if ($element instanceof Proxy && ! $element->__isInitialized()) { + $element->__load(); + } + + // clearing owning side value + $targetMetadata->reflFields[$mapping['mappedBy']]->setValue($element, null); + + $this->uow->computeChangeSet($targetMetadata, $element); + $persister->update($element); + + return true; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 6005dda6c..0d2709e82 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -402,90 +402,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a managed entity should cause no query to be executed."); } - /** - * @group DDC-2504 - */ - public function testRemovalOfManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() - { - $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); - $childClass = $this->_em->find(DDC2504ChildClass::CLASSNAME, $this->ddc2504ChildClassId); - - $queryCount = $this->getCurrentQueryCount(); - - $otherClass->childClasses->removeElement($childClass); - - $this->assertFalse($otherClass->childClasses->isInitialized(), 'Collection is not initialized.'); - - $this->assertEquals( - $queryCount + 1, - $this->getCurrentQueryCount(), - 'The owning side of the association is updated' - ); - - $this->assertFalse($otherClass->childClasses->contains($childClass)); - } - - /** - * @group DDC-2504 - */ - public function testRemovalOfNonManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() - { - $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); - $queryCount = $this->getCurrentQueryCount(); - - $otherClass->childClasses->removeElement(new DDC2504ChildClass()); - - $this->assertEquals( - $queryCount, - $this->getCurrentQueryCount(), - 'Removing an unmanaged entity should cause no query to be executed.' - ); - } - - /** - * @group DDC-2504 - */ - public function testRemovalOfNewElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() - { - $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); - $childClass = new DDC2504ChildClass(); - - $this->_em->persist($childClass); - - $queryCount = $this->getCurrentQueryCount(); - - $otherClass->childClasses->removeElement($childClass); - - $this->assertEquals( - $queryCount, - $this->getCurrentQueryCount(), - 'Removing a new entity should cause no query to be executed.' - ); - } - - /** - * @group DDC-2504 - */ - public function testRemovalOfNewManagedElementFromOneToManyJoinedInheritanceCollectionDoesNotInitializeIt() - { - $otherClass = $this->_em->find(DDC2504OtherClass::CLASSNAME, $this->ddc2504OtherClassId); - $childClass = new DDC2504ChildClass(); - - $this->_em->persist($childClass); - $this->_em->flush(); - - $queryCount = $this->getCurrentQueryCount(); - - $otherClass->childClasses->removeElement($childClass); - - $this->assertEquals( - $queryCount, - $this->getCurrentQueryCount(), - 'No queries are executed, as the owning side of the association is not actually updated.' - ); - $this->assertFalse($otherClass->childClasses->isInitialized(), 'Collection is not initialized.'); - } - /** * */ diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php index c323a44d8..a0d242fda 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\ORM\Functional\ValueConversionType; use Doctrine\Tests\Models\Tweet\Tweet; use Doctrine\Tests\Models\Tweet\User; -use Doctrine\Tests\Models\ValueConversionType as Entity; use Doctrine\Tests\OrmFunctionalTestCase; /** @@ -21,89 +20,8 @@ class OneToManyExtraLazyTest extends OrmFunctionalTestCase public function setUp() { $this->useModelSet('tweet'); - $this->useModelSet('vct_onetomany_extralazy'); parent::setUp(); - - $inversed = new Entity\InversedOneToManyExtraLazyEntity(); - $inversed->id1 = 'abc'; - - $owning1 = new Entity\OwningManyToOneExtraLazyEntity(); - $owning1->id2 = 'def'; - - $owning2 = new Entity\OwningManyToOneExtraLazyEntity(); - $owning2->id2 = 'ghi'; - - $owning3 = new Entity\OwningManyToOneExtraLazyEntity(); - $owning3->id2 = 'jkl'; - - $inversed->associatedEntities->add($owning1); - $owning1->associatedEntity = $inversed; - $inversed->associatedEntities->add($owning2); - $owning2->associatedEntity = $inversed; - $inversed->associatedEntities->add($owning3); - $owning3->associatedEntity = $inversed; - - $this->_em->persist($inversed); - $this->_em->persist($owning1); - $this->_em->persist($owning2); - $this->_em->persist($owning3); - - $this->_em->flush(); - $this->_em->clear(); - } - - public static function tearDownAfterClass() - { - $conn = static::$_sharedConn; - - $conn->executeUpdate('DROP TABLE vct_owning_manytoone_extralazy'); - $conn->executeUpdate('DROP TABLE vct_inversed_onetomany_extralazy'); - } - - public function testThatExtraLazyCollectionIsCounted() - { - $inversed = $this->_em->find( - 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', - 'abc' - ); - - $this->assertEquals(3, $inversed->associatedEntities->count()); - } - - public function testThatExtraLazyCollectionContainsAnEntity() - { - $inversed = $this->_em->find( - 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', - 'abc' - ); - - $owning = $this->_em->find( - 'Doctrine\Tests\Models\ValueConversionType\OwningManyToOneExtraLazyEntity', - 'def' - ); - - $this->assertTrue($inversed->associatedEntities->contains($owning)); - } - - public function testThatExtraLazyCollectionContainsAnIndexbyKey() - { - $inversed = $this->_em->find( - 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', - 'abc' - ); - - $this->assertTrue($inversed->associatedEntities->containsKey('def')); - } - - public function testThatASliceOfTheExtraLazyCollectionIsLoaded() - { - $inversed = $this->_em->find( - 'Doctrine\Tests\Models\ValueConversionType\InversedOneToManyExtraLazyEntity', - 'abc' - ); - - $this->assertCount(2, $inversed->associatedEntities->slice(0, 2)); } /** diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index d2a41cfb9..ff0f2cb53 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -139,6 +139,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase 'Doctrine\Tests\Models\StockExchange\Stock', 'Doctrine\Tests\Models\StockExchange\Market', ), + 'tweet' => array( + 'Doctrine\Tests\Models\Tweet\Tweet', + 'Doctrine\Tests\Models\Tweet\User', + ), 'legacy' => array( 'Doctrine\Tests\Models\Legacy\LegacyUser', 'Doctrine\Tests\Models\Legacy\LegacyUserReference', @@ -269,6 +273,10 @@ abstract class OrmFunctionalTestCase extends OrmTestCase $conn->executeUpdate('DELETE FROM exchange_stocks'); $conn->executeUpdate('DELETE FROM exchange_markets'); } + if (isset($this->_usedModelSets['tweet'])) { + $conn->executeUpdate('DELETE FROM tweet_tweet'); + $conn->executeUpdate('DELETE FROM tweet_user'); + } if (isset($this->_usedModelSets['legacy'])) { $conn->executeUpdate('DELETE FROM legacy_users_cars'); $conn->executeUpdate('DELETE FROM legacy_users_reference'); From 51250e987ed7b5832e1bc61597d655394936a45c Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Sat, 24 Jan 2015 12:51:19 +0100 Subject: [PATCH 14/14] #1169 DDC-3343 - moved tests to correct test class --- .../Functional/ExtraLazyCollectionTest.php | 100 ++++++++++++++ .../OneToManyExtraLazyTest.php | 123 ------------------ 2 files changed, 100 insertions(+), 123 deletions(-) delete mode 100644 tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 0d2709e82..42d8020d3 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -3,6 +3,8 @@ namespace Doctrine\Tests\ORM\Functional; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\Tests\Models\Tweet\Tweet; +use Doctrine\Tests\Models\Tweet\User; require_once __DIR__ . '/../../TestInit.php'; @@ -22,6 +24,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase public function setUp() { + $this->useModelSet('tweet'); $this->useModelSet('cms'); parent::setUp(); @@ -651,4 +654,101 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->topic = $article1->topic; $this->phonenumber = $phonenumber1->phonenumber; } + + /** + * @group DDC-3343 + */ + public function testRemovesManagedElementFromOneToManyExtraLazyCollection() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->tweets); + } + + /** + * @group DDC-3343 + */ + public function testRemovesManagedElementFromOneToManyExtraLazyCollectionWithoutDeletingTheTargetEntityEntry() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweetId); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); + + $this->assertNull($tweet->author, 'Tweet author link has been removed'); + } + + /** + * @group DDC-3343 + */ + public function testRemovingManagedLazyProxyFromExtraLazyOneToManyDoesRemoveTheAssociationButNotTheEntity() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + $tweet = $this->_em->getReference(Tweet::CLASSNAME, $tweetId); + + $user->tweets->removeElement($this->_em->getReference(Tweet::CLASSNAME, $tweetId)); + + $this->_em->clear(); + + /* @var $tweet Tweet */ + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); + $this->assertInstanceOf( + Tweet::CLASSNAME, + $tweet, + 'Even though the collection is extra lazy, the tweet should not have been deleted' + ); + + $this->assertNull($tweet->author); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->tweets); + } + + /** + * @return int[] ordered tuple: user id and tweet id + */ + private function loadTweetFixture() + { + $user = new User(); + $tweet = new Tweet(); + + $user->name = 'ocramius'; + $tweet->content = 'The cat is on the table'; + + $user->addTweet($tweet); + + $this->_em->persist($user); + $this->_em->persist($tweet); + $this->_em->flush(); + $this->_em->clear(); + + return array($user->id, $tweet->id); + } } diff --git a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php b/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php deleted file mode 100644 index a0d242fda..000000000 --- a/tests/Doctrine/Tests/ORM/Functional/ValueConversionType/OneToManyExtraLazyTest.php +++ /dev/null @@ -1,123 +0,0 @@ -useModelSet('tweet'); - - parent::setUp(); - } - - /** - * @group DDC-3343 - */ - public function testRemovesManagedElementFromOneToManyExtraLazyCollection() - { - list($userId, $tweetId) = $this->loadTweetFixture(); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $userId); - - $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); - - $this->_em->clear(); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $userId); - - $this->assertCount(0, $user->tweets); - } - - /** - * @group DDC-3343 - */ - public function testRemovesManagedElementFromOneToManyExtraLazyCollectionWithoutDeletingTheTargetEntityEntry() - { - list($userId, $tweetId) = $this->loadTweetFixture(); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $userId); - - $user->tweets->removeElement($this->_em->find(Tweet::CLASSNAME, $tweetId)); - - $this->_em->clear(); - - /* @var $tweet Tweet */ - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweetId); - $this->assertInstanceOf( - Tweet::CLASSNAME, - $tweet, - 'Even though the collection is extra lazy, the tweet should not have been deleted' - ); - - $this->assertNull($tweet->author, 'Tweet author link has been removed'); - } - - /** - * @group DDC-3343 - */ - public function testRemovingManagedLazyProxyFromExtraLazyOneToManyDoesRemoveTheAssociationButNotTheEntity() - { - list($userId, $tweetId) = $this->loadTweetFixture(); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $userId); - $tweet = $this->_em->getReference(Tweet::CLASSNAME, $tweetId); - - $user->tweets->removeElement($this->_em->getReference(Tweet::CLASSNAME, $tweetId)); - - $this->_em->clear(); - - /* @var $tweet Tweet */ - $tweet = $this->_em->find(Tweet::CLASSNAME, $tweet->id); - $this->assertInstanceOf( - Tweet::CLASSNAME, - $tweet, - 'Even though the collection is extra lazy, the tweet should not have been deleted' - ); - - $this->assertNull($tweet->author); - - /* @var $user User */ - $user = $this->_em->find(User::CLASSNAME, $userId); - - $this->assertCount(0, $user->tweets); - } - - /** - * @return int[] ordered tuple: user id and tweet id - */ - private function loadTweetFixture() - { - $user = new User(); - $tweet = new Tweet(); - - $user->name = 'ocramius'; - $tweet->content = 'The cat is on the table'; - - $user->addTweet($tweet); - - $this->_em->persist($user); - $this->_em->persist($tweet); - $this->_em->flush(); - $this->_em->clear(); - - return array($user->id, $tweet->id); - } -}