{"action":"created","comment":{"url":"https://api.github.com/repos/doctrine/doctrine2/pulls/comments/81562383","pull_request_review_id":2533084,"id":81562383,"diff_hunk":"@@ -0,0 +1,167 @@\n+<?php\n+\n+namespace Doctrine\\Tests\\Functional\\Ticket;\n+\n+use Doctrine\\ORM\\Event\\PreFlushEventArgs;\n+use Doctrine\\ORM\\Events;\n+\n+class Ticket5848Test extends \\Doctrine\\Tests\\OrmFunctionalTestCase\n+{\n+    private $collector;\n+    private $listener;\n+\n+    protected function setUp()\n+    {\n+        parent::setUp();\n+        $this->collector = new Ticket5848EntityCollector();\n+        $this->listener  = new Ticket5848PreFlushListener();\n+\n+        $this->listener->collector = $this->collector;\n+\n+        try {\n+            $this->_schemaTool->createSchema(array(\n+                $this->_em->getClassMetadata(__NAMESPACE__ . '\\Ticket5848Authentication'),\n+                $this->_em->getClassMetadata(__NAMESPACE__ . '\\Ticket5848Client'),\n+            ));\n+        } catch (\\Exception $e) {\n+            // Swallow all exceptions. We do not test the schema tool here.\n+        }\n+\n+\n+        $this->_em->getEventManager()->addEventListener(Events::preFlush, $this->listener);\n+    }\n+\n+    public function testExplicitFlushWithOne()\n+    {\n+        $e = new Ticket5848Client();\n+\n+        $this->_em->persist($e);\n+        $this->_em->flush($e);\n+\n+        self::assertSame($e, $this->collector->entities[0]);\n+    }\n+\n+    public function testExplicitFlushWithMany()\n+    {\n+        $e1 = new Ticket5848Client();\n+        $e2 = new Ticket5848Authentication();\n+        $e3 = new Ticket5848Client();\n+\n+        $this->_em->persist($e1);\n+        $this->_em->persist($e2);\n+        $this->_em->persist($e3);\n+        $this->_em->flush([$e1, $e2]);\n+\n+        self::assertSame($e1, $this->collector->entities[0]);\n+        self::assertSame($e2, $this->collector->entities[1]);\n+    }\n+\n+    public function testExplicitFlushWithConsecutiveFlushes()\n+    {\n+        $e1 = new Ticket5848Client();\n+        $e2 = new Ticket5848Authentication();\n+        $e3 = new Ticket5848Client();\n+\n+        $this->_em->persist($e1);\n+        $this->_em->persist($e2);\n+        $this->_em->persist($e3);\n+        $this->_em->flush([$e1, $e2]);\n+        $this->_em->flush($e3);\n+\n+        self::assertSame($e3, $this->collector->entities[0]);\n+    }\n+\n+    public function testImplicitFlush()\n+    {\n+        $e1 = new Ticket5848Client();\n+        $e2 = new Ticket5848Authentication();\n+        $e3 = new Ticket5848Client();\n+\n+        $this->_em->persist($e1);\n+        $this->_em->persist($e2);\n+        $this->_em->persist($e3);\n+        $this->_em->flush();\n+\n+        self::assertSame($e1, $this->collector->entities[0]);\n+        self::assertSame($e2, $this->collector->entities[1]);\n+        self::assertSame($e3, $this->collector->entities[2]);\n+    }\n+\n+    public function testExplicitFlushAfterImplicitFlush()\n+    {\n+        $e1 = new Ticket5848Client();\n+        $e2 = new Ticket5848Authentication();\n+        $e3 = new Ticket5848Client();\n+\n+        $this->_em->persist($e1);\n+        $this->_em->persist($e2);\n+        $this->_em->persist($e3);\n+        $this->_em->flush();\n+\n+        self::assertSame($e1, $this->collector->entities[0]);\n+        self::assertSame($e2, $this->collector->entities[1]);\n+        self::assertSame($e3, $this->collector->entities[2]);\n+\n+        $e2->username = 'foo';\n+\n+        $this->_em->flush([$e2, $e3]);\n+\n+        self::assertSame($e2, $this->collector->entities[0]);\n+        self::assertSame($e3, $this->collector->entities[1]);\n+    }\n+}\n+\n+class Ticket5848PreFlushListener\n+{\n+    public $collector;\n+\n+    public function preFlush(PreFlushEventArgs $event)\n+    {\n+        if (!$event->hasEntities()) {\n+            $uow = $event->getEntityManager()->getUnitOfWork();\n+            $uow->computeChangeSets();","path":"tests/Doctrine/Tests/ORM/Functional/Ticket/Ticket5848Test.php","position":122,"original_position":122,"commit_id":"a403339a55a01a67bb49adbf1b721ec3edc57c86","original_commit_id":"a403339a55a01a67bb49adbf1b721ec3edc57c86","user":{"login":"andreas-glaser","id":2282942,"avatar_url":"https://avatars.githubusercontent.com/u/2282942?v=3","gravatar_id":"","url":"https://api.github.com/users/andreas-glaser","html_url":"https://github.com/andreas-glaser","followers_url":"https://api.github.com/users/andreas-glaser/followers","following_url":"https://api.github.com/users/andreas-glaser/following{/other_user}","gists_url":"https://api.github.com/users/andreas-glaser/gists{/gist_id}","starred_url":"https://api.github.com/users/andreas-glaser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/andreas-glaser/subscriptions","organizations_url":"https://api.github.com/users/andreas-glaser/orgs","repos_url":"https://api.github.com/users/andreas-glaser/repos","events_url":"https://api.github.com/users/andreas-glaser/events{/privacy}","received_events_url":"https://api.github.com/users/andreas-glaser/received_events","type":"User","site_admin":false},"body":"It does but that is just this particular use case. Having the entity list (or empty list) here will open up a whole new range of possibilities that could be done before doctrine actually processes the change set.","created_at":"2016-10-03T14:34:14Z","updated_at":"2016-10-03T14:34:14Z","html_url":"https://github.com/doctrine/doctrine2/pull/5848#discussion_r81562383","pull_request_url":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848","_links":{"self":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/comments/81562383"},"html":{"href":"https://github.com/doctrine/doctrine2/pull/5848#discussion_r81562383"},"pull_request":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848"}}},"pull_request":{"url":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848","id":72477203,"html_url":"https://github.com/doctrine/doctrine2/pull/5848","diff_url":"https://github.com/doctrine/doctrine2/pull/5848.diff","patch_url":"https://github.com/doctrine/doctrine2/pull/5848.patch","issue_url":"https://api.github.com/repos/doctrine/doctrine2/issues/5848","number":5848,"state":"open","locked":false,"title":"Pre-flush event knows which entities are being flushed","user":{"login":"iltar","id":1754678,"avatar_url":"https://avatars.githubusercontent.com/u/1754678?v=3","gravatar_id":"","url":"https://api.github.com/users/iltar","html_url":"https://github.com/iltar","followers_url":"https://api.github.com/users/iltar/followers","following_url":"https://api.github.com/users/iltar/following{/other_user}","gists_url":"https://api.github.com/users/iltar/gists{/gist_id}","starred_url":"https://api.github.com/users/iltar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iltar/subscriptions","organizations_url":"https://api.github.com/users/iltar/orgs","repos_url":"https://api.github.com/users/iltar/repos","events_url":"https://api.github.com/users/iltar/events{/privacy}","received_events_url":"https://api.github.com/users/iltar/received_events","type":"User","site_admin":false},"body":"**short description**\r\nThis PR focuses on adding the entities which are being flushed for explicit flushes to the PreFlushEvent (and if desired I can add other events too)\r\n\r\n**A bit of background info**\r\nFor an event listener we need to know which fields have changed in an entity and we fire a custom entity changed event in case the entity is tracked. For normal requests this works fine but we hit a bottleneck in larger batches. The challenge we are facing is that we need to know if:\r\n - The entity is tracked by our listener (`@Tracked` annotation)\r\n - The entity state is changed (1 level deep, not recursive)\r\n\r\nWe're doing this pre-flush so that additional changes/new entities can be created and added to the 'to-be-changed-set', which results in being unable to use the doctrine changeset computation as it would run twice. We've created a lightweight variant for this but this is called for every single entity. We also create a new \"entity\" and use the hydration to create as it was in its original state when hydrated for the first time. This means we can compare/absorb the objects and know the exact changes and pass this along to our event: https://github.com/hostnet/entity-tracker-component/blob/master/src/Listener/EntityChangedListener.php\r\n\r\nAs we need to know which entities have changed to calculate the mutations and fire events, we have to check the internal state of the Unit of Work and calculate this. This is what you would expect from a `flush()`. However, if you have 1000 entities in memory and an explicit flush is done `flush(...)` or `flush([...]);` you already know which entities will be flushed. This makes it meaningless to iterate over all managed entities.\r\n\r\n\r\nIf this change is something you want to add, I will add tests (can't run the tests locally).\r\n","created_at":"2016-06-03T09:19:01Z","updated_at":"2016-10-03T14:34:14Z","closed_at":null,"merged_at":null,"merge_commit_sha":"763fad326b5b47bc64046ecab7ad41d62f19523a","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848/commits","review_comments_url":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848/comments","review_comment_url":"https://api.github.com/repos/doctrine/doctrine2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/doctrine/doctrine2/issues/5848/comments","statuses_url":"https://api.github.com/repos/doctrine/doctrine2/statuses/a403339a55a01a67bb49adbf1b721ec3edc57c86","head":{"label":"iltar:feature/pre-flush-entity-args","ref":"feature/pre-flush-entity-args","sha":"a403339a55a01a67bb49adbf1b721ec3edc57c86","user":{"login":"iltar","id":1754678,"avatar_url":"https://avatars.githubusercontent.com/u/1754678?v=3","gravatar_id":"","url":"https://api.github.com/users/iltar","html_url":"https://github.com/iltar","followers_url":"https://api.github.com/users/iltar/followers","following_url":"https://api.github.com/users/iltar/following{/other_user}","gists_url":"https://api.github.com/users/iltar/gists{/gist_id}","starred_url":"https://api.github.com/users/iltar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iltar/subscriptions","organizations_url":"https://api.github.com/users/iltar/orgs","repos_url":"https://api.github.com/users/iltar/repos","events_url":"https://api.github.com/users/iltar/events{/privacy}","received_events_url":"https://api.github.com/users/iltar/received_events","type":"User","site_admin":false},"repo":{"id":17061140,"name":"doctrine2","full_name":"iltar/doctrine2","owner":{"login":"iltar","id":1754678,"avatar_url":"https://avatars.githubusercontent.com/u/1754678?v=3","gravatar_id":"","url":"https://api.github.com/users/iltar","html_url":"https://github.com/iltar","followers_url":"https://api.github.com/users/iltar/followers","following_url":"https://api.github.com/users/iltar/following{/other_user}","gists_url":"https://api.github.com/users/iltar/gists{/gist_id}","starred_url":"https://api.github.com/users/iltar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iltar/subscriptions","organizations_url":"https://api.github.com/users/iltar/orgs","repos_url":"https://api.github.com/users/iltar/repos","events_url":"https://api.github.com/users/iltar/events{/privacy}","received_events_url":"https://api.github.com/users/iltar/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/iltar/doctrine2","description":"Doctrine 2 Object Relational Mapper","fork":true,"url":"https://api.github.com/repos/iltar/doctrine2","forks_url":"https://api.github.com/repos/iltar/doctrine2/forks","keys_url":"https://api.github.com/repos/iltar/doctrine2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/iltar/doctrine2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/iltar/doctrine2/teams","hooks_url":"https://api.github.com/repos/iltar/doctrine2/hooks","issue_events_url":"https://api.github.com/repos/iltar/doctrine2/issues/events{/number}","events_url":"https://api.github.com/repos/iltar/doctrine2/events","assignees_url":"https://api.github.com/repos/iltar/doctrine2/assignees{/user}","branches_url":"https://api.github.com/repos/iltar/doctrine2/branches{/branch}","tags_url":"https://api.github.com/repos/iltar/doctrine2/tags","blobs_url":"https://api.github.com/repos/iltar/doctrine2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/iltar/doctrine2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/iltar/doctrine2/git/refs{/sha}","trees_url":"https://api.github.com/repos/iltar/doctrine2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/iltar/doctrine2/statuses/{sha}","languages_url":"https://api.github.com/repos/iltar/doctrine2/languages","stargazers_url":"https://api.github.com/repos/iltar/doctrine2/stargazers","contributors_url":"https://api.github.com/repos/iltar/doctrine2/contributors","subscribers_url":"https://api.github.com/repos/iltar/doctrine2/subscribers","subscription_url":"https://api.github.com/repos/iltar/doctrine2/subscription","commits_url":"https://api.github.com/repos/iltar/doctrine2/commits{/sha}","git_commits_url":"https://api.github.com/repos/iltar/doctrine2/git/commits{/sha}","comments_url":"https://api.github.com/repos/iltar/doctrine2/comments{/number}","issue_comment_url":"https://api.github.com/repos/iltar/doctrine2/issues/comments{/number}","contents_url":"https://api.github.com/repos/iltar/doctrine2/contents/{+path}","compare_url":"https://api.github.com/repos/iltar/doctrine2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/iltar/doctrine2/merges","archive_url":"https://api.github.com/repos/iltar/doctrine2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/iltar/doctrine2/downloads","issues_url":"https://api.github.com/repos/iltar/doctrine2/issues{/number}","pulls_url":"https://api.github.com/repos/iltar/doctrine2/pulls{/number}","milestones_url":"https://api.github.com/repos/iltar/doctrine2/milestones{/number}","notifications_url":"https://api.github.com/repos/iltar/doctrine2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/iltar/doctrine2/labels{/name}","releases_url":"https://api.github.com/repos/iltar/doctrine2/releases{/id}","deployments_url":"https://api.github.com/repos/iltar/doctrine2/deployments","created_at":"2014-02-21T15:52:03Z","updated_at":"2016-06-03T08:05:38Z","pushed_at":"2016-06-03T15:23:47Z","git_url":"git://github.com/iltar/doctrine2.git","ssh_url":"git@github.com:iltar/doctrine2.git","clone_url":"https://github.com/iltar/doctrine2.git","svn_url":"https://github.com/iltar/doctrine2","homepage":"http://www.doctrine-project.org","size":26249,"stargazers_count":0,"watchers_count":0,"language":"PHP","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"doctrine:master","ref":"master","sha":"1c2b7c968561f2e319117d7860c88e8c0cad3c7a","user":{"login":"doctrine","id":209254,"avatar_url":"https://avatars.githubusercontent.com/u/209254?v=3","gravatar_id":"","url":"https://api.github.com/users/doctrine","html_url":"https://github.com/doctrine","followers_url":"https://api.github.com/users/doctrine/followers","following_url":"https://api.github.com/users/doctrine/following{/other_user}","gists_url":"https://api.github.com/users/doctrine/gists{/gist_id}","starred_url":"https://api.github.com/users/doctrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doctrine/subscriptions","organizations_url":"https://api.github.com/users/doctrine/orgs","repos_url":"https://api.github.com/users/doctrine/repos","events_url":"https://api.github.com/users/doctrine/events{/privacy}","received_events_url":"https://api.github.com/users/doctrine/received_events","type":"Organization","site_admin":false},"repo":{"id":597887,"name":"doctrine2","full_name":"doctrine/doctrine2","owner":{"login":"doctrine","id":209254,"avatar_url":"https://avatars.githubusercontent.com/u/209254?v=3","gravatar_id":"","url":"https://api.github.com/users/doctrine","html_url":"https://github.com/doctrine","followers_url":"https://api.github.com/users/doctrine/followers","following_url":"https://api.github.com/users/doctrine/following{/other_user}","gists_url":"https://api.github.com/users/doctrine/gists{/gist_id}","starred_url":"https://api.github.com/users/doctrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/doctrine/subscriptions","organizations_url":"https://api.github.com/users/doctrine/orgs","repos_url":"https://api.github.com/users/doctrine/repos","events_url":"https://api.github.com/users/doctrine/events{/privacy}","received_events_url":"https://api.github.com/users/doctrine/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/doctrine/doctrine2","description":"Doctrine 2 Object Relational Mapper (ORM)","fork":false,"url":"https://api.github.com/repos/doctrine/doctrine2","forks_url":"https://api.github.com/repos/doctrine/doctrine2/forks","keys_url":"https://api.github.com/repos/doctrine/doctrine2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/doctrine/doctrine2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/doctrine/doctrine2/teams","hooks_url":"https://api.github.com/repos/doctrine/doctrine2/hooks","issue_events_url":"https://api.github.com/repos/doctrine/doctrine2/issues/events{/number}","events_url":"https://api.github.com/repos/doctrine/doctrine2/events","assignees_url":"https://api.github.com/repos/doctrine/doctrine2/assignees{/user}","branches_url":"https://api.github.com/repos/doctrine/doctrine2/branches{/branch}","tags_url":"https://api.github.com/repos/doctrine/doctrine2/tags","blobs_url":"https://api.github.com/repos/doctrine/doctrine2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/doctrine/doctrine2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/doctrine/doctrine2/git/refs{/sha}","trees_url":"https://api.github.com/repos/doctrine/doctrine2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/doctrine/doctrine2/statuses/{sha}","languages_url":"https://api.github.com/repos/doctrine/doctrine2/languages","stargazers_url":"https://api.github.com/repos/doctrine/doctrine2/stargazers","contributors_url":"https://api.github.com/repos/doctrine/doctrine2/contributors","subscribers_url":"https://api.github.com/repos/doctrine/doctrine2/subscribers","subscription_url":"https://api.github.com/repos/doctrine/doctrine2/subscription","commits_url":"https://api.github.com/repos/doctrine/doctrine2/commits{/sha}","git_commits_url":"https://api.github.com/repos/doctrine/doctrine2/git/commits{/sha}","comments_url":"https://api.github.com/repos/doctrine/doctrine2/comments{/number}","issue_comment_url":"https://api.github.com/repos/doctrine/doctrine2/issues/comments{/number}","contents_url":"https://api.github.com/repos/doctrine/doctrine2/contents/{+path}","compare_url":"https://api.github.com/repos/doctrine/doctrine2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/doctrine/doctrine2/merges","archive_url":"https://api.github.com/repos/doctrine/doctrine2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/doctrine/doctrine2/downloads","issues_url":"https://api.github.com/repos/doctrine/doctrine2/issues{/number}","pulls_url":"https://api.github.com/repos/doctrine/doctrine2/pulls{/number}","milestones_url":"https://api.github.com/repos/doctrine/doctrine2/milestones{/number}","notifications_url":"https://api.github.com/repos/doctrine/doctrine2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/doctrine/doctrine2/labels{/name}","releases_url":"https://api.github.com/repos/doctrine/doctrine2/releases{/id}","deployments_url":"https://api.github.com/repos/doctrine/doctrine2/deployments","created_at":"2010-04-06T21:42:59Z","updated_at":"2016-09-29T22:05:03Z","pushed_at":"2016-10-03T11:15:34Z","git_url":"git://github.com/doctrine/doctrine2.git","ssh_url":"git@github.com:doctrine/doctrine2.git","clone_url":"https://github.com/doctrine/doctrine2.git","svn_url":"https://github.com/doctrine/doctrine2","homepage":"http://www.doctrine-project.org","size":38698,"stargazers_count":3237,"watchers_count":3237,"language":"PHP","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1581,"mirror_url":null,"open_issues_count":1143,"forks":1581,"open_issues":1143,"watchers":3237,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848"},"html":{"href":"https://github.com/doctrine/doctrine2/pull/5848"},"issue":{"href":"https://api.github.com/repos/doctrine/doctrine2/issues/5848"},"comments":{"href":"https://api.github.com/repos/doctrine/doctrine2/issues/5848/comments"},"review_comments":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848/comments"},"review_comment":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/doctrine/doctrine2/pulls/5848/commits"},"statuses":{"href":"https://api.github.com/repos/doctrine/doctrine2/statuses/a403339a55a01a67bb49adbf1b721ec3edc57c86"}}}}
{"actor":{"display_login":"andreas-glaser"}}