From af59ea962f15e70991caa32592a60278af2d23b2 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 27 Jan 2015 06:19:26 +0100 Subject: [PATCH 01/12] #1169 DDC-3343 - updating test expectations - one-to-many changes should be no-op unless orphan removal is specified. --- .../Functional/ExtraLazyCollectionTest.php | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 42d8020d3..ab160d384 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -653,6 +653,110 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->topic = $article1->topic; $this->phonenumber = $phonenumber1->phonenumber; + + } + + /** + * @group DDC-3343 + */ + public function testRemoveManagedElementFromOneToManyExtraLazyCollectionIsNoOp() + { + 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(1, $user->tweets, 'Element was not removed - need to update the owning side first'); + } + + /** + * @group DDC-3343 + */ + public function testRemoveManagedElementFromOneToManyExtraLazyCollectionWithoutDeletingTheTargetEntityEntryIsNoOp() + { + list($userId, $tweetId) = $this->loadTweetFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $e = $this->_em->find(Tweet::CLASSNAME, $tweetId); + + $user->tweets->removeElement($e); + + $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->assertInstanceOf( + User::CLASSNAME, + $tweet->author, + 'Tweet author link has not been removed - need to update the owning side first' + ); + } + + /** + * @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(1, $user->tweets, 'Element was not removed - need to update the owning side first'); + } + + /** + * @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); } /** From 94c0e46c96e5be6eba2033a9bb313e51ba1d2ef9 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 27 Jan 2015 06:26:55 +0100 Subject: [PATCH 02/12] #1169 DDC-3343 - updating test expectations - one-to-many changes should be no-op unless orphan removal is specified. --- tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index ab160d384..2aea54200 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -730,7 +730,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase 'Even though the collection is extra lazy, the tweet should not have been deleted' ); - $this->assertNull($tweet->author); + $this->assertInstanceOf(User::CLASSNAME, $tweet->author); /* @var $user User */ $user = $this->_em->find(User::CLASSNAME, $userId); From cbe5575f3877a23c725d030e98b2cad389235ca5 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 27 Jan 2015 07:42:48 +0100 Subject: [PATCH 03/12] #1169 DDC-3343 - adding tests for orphan-removal + extra-lazy + one-to-many element removal behavior --- tests/Doctrine/Tests/Models/Tweet/User.php | 14 ++- .../Doctrine/Tests/Models/Tweet/UserList.php | 29 +++++ .../Functional/ExtraLazyCollectionTest.php | 105 +++++++++++++++++- .../Doctrine/Tests/OrmFunctionalTestCase.php | 11 ++ 4 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/Models/Tweet/UserList.php diff --git a/tests/Doctrine/Tests/Models/Tweet/User.php b/tests/Doctrine/Tests/Models/Tweet/User.php index 4722e6317..68cf137f2 100644 --- a/tests/Doctrine/Tests/Models/Tweet/User.php +++ b/tests/Doctrine/Tests/Models/Tweet/User.php @@ -29,9 +29,15 @@ class User */ public $tweets; + /** + * @OneToMany(targetEntity="UserList", mappedBy="owner", fetch="EXTRA_LAZY", orphanRemoval=true) + */ + public $userLists; + public function __construct() { - $this->tweets = new ArrayCollection(); + $this->tweets = new ArrayCollection(); + $this->userLists = new ArrayCollection(); } public function addTweet(Tweet $tweet) @@ -39,4 +45,10 @@ class User $tweet->setAuthor($this); $this->tweets->add($tweet); } + + public function addUserList(UserList $userList) + { + $userList->owner = $this; + $this->userLists->add($userList); + } } diff --git a/tests/Doctrine/Tests/Models/Tweet/UserList.php b/tests/Doctrine/Tests/Models/Tweet/UserList.php new file mode 100644 index 000000000..1eb3e141f --- /dev/null +++ b/tests/Doctrine/Tests/Models/Tweet/UserList.php @@ -0,0 +1,29 @@ +_em->find(User::CLASSNAME, $userId); + $tweet = $this->_em->find(Tweet::CLASSNAME, $tweetId); - $e = $this->_em->find(Tweet::CLASSNAME, $tweetId); - - $user->tweets->removeElement($e); + $user->tweets->removeElement($tweet); $this->_em->clear(); @@ -835,6 +836,83 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertCount(0, $user->tweets); } + /** + * @group DDC-3343 + */ + public function testRemoveOrphanedManagedElementFromOneToManyExtraLazyCollection() + { + list($userId, $userListId) = $this->loadUserListFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->find(UserList::CLASSNAME, $userListId)); + + $this->_em->clear(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->userLists, 'Element was removed from association due to orphan removal'); + $this->assertNull( + $this->_em->find(UserList::CLASSNAME, $userListId), + 'Element was deleted due to orphan removal' + ); + } + + /** + * @group DDC-3343 + */ + public function testRemoveOrphanedUnManagedElementFromOneToManyExtraLazyCollection() + { + list($userId, $userListId) = $this->loadUserListFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->userLists->removeElement(new UserList()); + + $this->_em->clear(); + + /* @var $userList UserList */ + $userList = $this->_em->find(UserList::CLASSNAME, $userListId); + $this->assertInstanceOf( + UserList::CLASSNAME, + $userList, + 'Even though the collection is extra lazy + orphan removal, the user list should not have been deleted' + ); + + $this->assertInstanceOf( + User::CLASSNAME, + $userList->owner, + 'User list to owner link has not been removed' + ); + } + + /** + * @group DDC-3343 + */ + public function testRemoveOrphanedManagedLazyProxyFromExtraLazyOneToMany() + { + list($userId, $userListId) = $this->loadUserListFixture(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $user->tweets->removeElement($this->_em->getReference(UserList::CLASSNAME, $userListId)); + + $this->_em->clear(); + + /* @var $user User */ + $user = $this->_em->find(User::CLASSNAME, $userId); + + $this->assertCount(0, $user->userLists, 'Element was removed from association due to orphan removal'); + $this->assertNull( + $this->_em->find(UserList::CLASSNAME, $userListId), + 'Element was deleted due to orphan removal' + ); + } + /** * @return int[] ordered tuple: user id and tweet id */ @@ -855,4 +933,25 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase return array($user->id, $tweet->id); } + + /** + * @return int[] ordered tuple: user id and user list id + */ + private function loadUserListFixture() + { + $user = new User(); + $userList = new UserList(); + + $user->name = 'ocramius'; + $userList->listName = 'PHP Developers to follow closely'; + + $user->addUserList($userList); + + $this->_em->persist($user); + $this->_em->persist($userList); + $this->_em->flush(); + $this->_em->clear(); + + return array($user->id, $userList->id); + } } diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index ff0f2cb53..b9ccbcb66 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -166,6 +166,11 @@ abstract class OrmFunctionalTestCase extends OrmTestCase 'Doctrine\Tests\Models\Taxi\Car', 'Doctrine\Tests\Models\Taxi\Driver', ), + 'tweet' => array( + 'Doctrine\Tests\Models\Tweet\User', + 'Doctrine\Tests\Models\Tweet\Tweet', + 'Doctrine\Tests\Models\Tweet\UserList', + ), ); /** @@ -305,6 +310,12 @@ abstract class OrmFunctionalTestCase extends OrmTestCase $conn->executeUpdate('DELETE FROM taxi_driver'); } + if (isset($this->_usedModelSets['tweet'])) { + $conn->executeUpdate('DELETE FROM tweet_tweet'); + $conn->executeUpdate('DELETE FROM tweet_user_list'); + $conn->executeUpdate('DELETE FROM tweet_user'); + } + $this->_em->clear(); } From fac410b213e941736f0fb952bdf1e63b83085114 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 29 Jan 2015 18:39:30 +0000 Subject: [PATCH 04/12] #1169 DDC-3343 - aligning test suite logic to the 2.5 branch (failing tests) --- tests/Doctrine/Tests/Models/Tweet/Tweet.php | 13 ++++++++----- .../ORM/Functional/ExtraLazyCollectionTest.php | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/Doctrine/Tests/Models/Tweet/Tweet.php b/tests/Doctrine/Tests/Models/Tweet/Tweet.php index 8a315df9e..14411dc2a 100644 --- a/tests/Doctrine/Tests/Models/Tweet/Tweet.php +++ b/tests/Doctrine/Tests/Models/Tweet/Tweet.php @@ -18,17 +18,20 @@ class Tweet public $id; /** - * @Column(type="string") + * @Column(type="string", length=140) */ - public $content; + public $content = ''; /** - * @ManyToOne(targetEntity="User", inversedBy="tweets") + * @ManyToOne(targetEntity="User", inversedBy="tweets", cascade={"persist"}, fetch="EXTRA_LAZY") */ public $author; - public function setAuthor(User $user) + /** + * @param User $author + */ + public function setAuthor(User $author) { - $this->author = $user; + $this->user = $author; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 6633f0c24..2c6fd6faf 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -28,6 +28,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase { $this->useModelSet('tweet'); $this->useModelSet('cms'); + $this->useModelSet('tweet'); parent::setUp(); $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); From 4884183b957dd2e481ba17f203a863b8424ba809 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:11:19 +0000 Subject: [PATCH 05/12] #1169 DDC-3343 - fixing test case typos (referencing wrong/inexisting properties, inexisting owning side assigned --- tests/Doctrine/Tests/Models/Tweet/Tweet.php | 2 +- .../Tests/ORM/Functional/ExtraLazyCollectionTest.php | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tests/Doctrine/Tests/Models/Tweet/Tweet.php b/tests/Doctrine/Tests/Models/Tweet/Tweet.php index 14411dc2a..9f564e27b 100644 --- a/tests/Doctrine/Tests/Models/Tweet/Tweet.php +++ b/tests/Doctrine/Tests/Models/Tweet/Tweet.php @@ -32,6 +32,6 @@ class Tweet */ public function setAuthor(User $author) { - $this->user = $author; + $this->author = $author; } } diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 2c6fd6faf..daf7a2613 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -369,8 +369,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $user->articles->removeElement($article); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); - // NOTE: +2 queries because CmsArticle is a versioned entity, and that needs to be handled accordingly - $this->assertEquals($queryCount + 2, $this->getCurrentQueryCount()); + $this->assertEquals($queryCount, $this->getCurrentQueryCount()); // Test One to Many removal with Entity state as new $article = new \Doctrine\Tests\Models\CMS\CmsArticle(); @@ -391,7 +390,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $user->articles->removeElement($article); - $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a persisted entity will not cause queries when the owning side doesn't actually change."); + $this->assertEquals($queryCount, $this->getCurrentQueryCount(), "Removing a persisted entity should cause one query to be executed."); $this->assertFalse($user->articles->isInitialized(), "Post-Condition: Collection is not initialized."); // Test One to Many removal with Entity state as managed @@ -847,7 +846,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase /* @var $user User */ $user = $this->_em->find(User::CLASSNAME, $userId); - $user->tweets->removeElement($this->_em->find(UserList::CLASSNAME, $userListId)); + $user->userLists->removeElement($this->_em->find(UserList::CLASSNAME, $userListId)); $this->_em->clear(); @@ -900,7 +899,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase /* @var $user User */ $user = $this->_em->find(User::CLASSNAME, $userId); - $user->tweets->removeElement($this->_em->getReference(UserList::CLASSNAME, $userListId)); + $user->userLists->removeElement($this->_em->getReference(UserList::CLASSNAME, $userListId)); $this->_em->clear(); From 4bed15b9846932929294e6a0969ba8d867f428cc Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:11:53 +0000 Subject: [PATCH 06/12] #1169 DDC-3343 - one-to-many persister should only interact with the data when `orphanRemoval` and `EXTRA_LAZY` are combined --- lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php index cf39436d4..6e02272f4 100644 --- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -223,6 +223,13 @@ class OneToManyPersister extends AbstractCollectionPersister */ public function removeElement(PersistentCollection $coll, $element) { + $mapping = $coll->getMapping(); + + if ( ! $mapping['orphanRemoval']) { + // no-op: this is not the owning side, therefore no operations should be applied + return false; + } + $uow = $this->em->getUnitOfWork(); // shortcut for new entities @@ -238,9 +245,9 @@ class OneToManyPersister extends AbstractCollectionPersister return false; } - $mapping = $coll->getMapping(); - $persister = $this->uow->getEntityPersister($mapping['targetEntity']); - $targetMetadata = $this->em->getClassMetadata($mapping['targetEntity']); + $class = $this->em->getClassMetadata($mapping['targetEntity']); + $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform) + . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; if ($element instanceof Proxy && ! $element->__isInitialized()) { $element->__load(); From c6e7a8184973a4dc8432b9ce603bf9c422478594 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:21:28 +0000 Subject: [PATCH 07/12] #1169 DDC-3343 - removing duplicate test method --- .../Functional/ExtraLazyCollectionTest.php | 55 +------------------ 1 file changed, 1 insertion(+), 54 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index daf7a2613..06223e4e0 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -6,7 +6,6 @@ use Doctrine\ORM\Mapping\ClassMetadataInfo; use Doctrine\Tests\Models\Tweet\Tweet; use Doctrine\Tests\Models\Tweet\User; use Doctrine\Tests\Models\Tweet\UserList; -use Doctrine\Tests\OrmFunctionalTestCase; require_once __DIR__ . '/../../TestInit.php'; @@ -29,6 +28,7 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->useModelSet('tweet'); $this->useModelSet('cms'); $this->useModelSet('tweet'); + parent::setUp(); $class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsUser'); @@ -655,7 +655,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->topic = $article1->topic; $this->phonenumber = $phonenumber1->phonenumber; - } /** @@ -739,27 +738,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertCount(1, $user->tweets, 'Element was not removed - need to update the owning side first'); } - /** - * @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); - } - /** * @group DDC-3343 */ @@ -805,37 +783,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $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); - } - /** * @group DDC-3343 */ From c4ab4db743869f0ffd4e3efa3ece8b9e7733784a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:23:51 +0000 Subject: [PATCH 08/12] #1169 DDC-3343 - remove duplicate tests introduced by cherry-picking conflicts --- .../Functional/ExtraLazyCollectionTest.php | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php index 06223e4e0..8cb85b138 100644 --- a/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/ExtraLazyCollectionTest.php @@ -738,51 +738,6 @@ class ExtraLazyCollectionTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertCount(1, $user->tweets, 'Element was not removed - need to update the owning side first'); } - /** - * @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 */ From 2fa48c6e8860bd056c9ff48fae9ea33a48e632c6 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:25:06 +0000 Subject: [PATCH 09/12] #1169 DDC-3343 - actually deleting associated elements when they are orphaned and EXTRA_LAZY is used --- lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php index 6e02272f4..539f13b14 100644 --- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -249,16 +249,6 @@ class OneToManyPersister extends AbstractCollectionPersister $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform) . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; - 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; + return (bool) $this->conn->executeUpdate($sql, $this->getDeleteRowSQLParameters($coll, $element)); } } From a1bd3e8cc9b36f180816917aa956251949c87a63 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:25:20 +0000 Subject: [PATCH 10/12] #1169 DDC-3343 - optimized imports --- lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php index 539f13b14..6e43ef29e 100644 --- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -19,7 +19,6 @@ namespace Doctrine\ORM\Persisters; -use Doctrine\Common\Proxy\Proxy; use Doctrine\ORM\PersistentCollection; use Doctrine\ORM\UnitOfWork; From f5705d6d954c97d98bbb00d4e0eaaed36edf1d92 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:52:54 +0000 Subject: [PATCH 11/12] #1169 DDC-3343 - corrected persister logic - only uses the entity persister to perform deletes on the owning side --- lib/Doctrine/ORM/Persisters/OneToManyPersister.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php index 6e43ef29e..b1ff59cdc 100644 --- a/lib/Doctrine/ORM/Persisters/OneToManyPersister.php +++ b/lib/Doctrine/ORM/Persisters/OneToManyPersister.php @@ -244,10 +244,11 @@ class OneToManyPersister extends AbstractCollectionPersister return false; } - $class = $this->em->getClassMetadata($mapping['targetEntity']); - $sql = 'DELETE FROM ' . $this->quoteStrategy->getTableName($class, $this->platform) - . ' WHERE ' . implode('= ? AND ', $class->getIdentifierColumnNames()) . ' = ?'; + $this + ->uow + ->getEntityPersister($mapping['targetEntity']) + ->delete($element); - return (bool) $this->conn->executeUpdate($sql, $this->getDeleteRowSQLParameters($coll, $element)); + return true; } } From 11936a6cac1a3100d0cc4cafa713bbcd57b124d7 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 5 Feb 2015 00:53:34 +0000 Subject: [PATCH 12/12] #1169 DDC-3343 - correcting functional test case cleanup logic (sorting deletes by FK dependencies) --- tests/Doctrine/Tests/OrmFunctionalTestCase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/Doctrine/Tests/OrmFunctionalTestCase.php b/tests/Doctrine/Tests/OrmFunctionalTestCase.php index b9ccbcb66..479887b92 100644 --- a/tests/Doctrine/Tests/OrmFunctionalTestCase.php +++ b/tests/Doctrine/Tests/OrmFunctionalTestCase.php @@ -280,6 +280,7 @@ abstract class OrmFunctionalTestCase extends OrmTestCase } if (isset($this->_usedModelSets['tweet'])) { $conn->executeUpdate('DELETE FROM tweet_tweet'); + $conn->executeUpdate('DELETE FROM tweet_user_list'); $conn->executeUpdate('DELETE FROM tweet_user'); } if (isset($this->_usedModelSets['legacy'])) {