diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index c0b0dd8c3..4f8ce32db 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -324,7 +324,7 @@ class UnitOfWork implements PropertyChangedListener } // Compute changes done since last commit. - if ($entity === null) { + if (null === $entity) { $this->computeChangeSets(); } elseif (is_object($entity)) { $this->computeSingleEntityChangeSet($entity); @@ -414,17 +414,40 @@ class UnitOfWork implements PropertyChangedListener $this->dispatchPostFlushEvent(); - // Clear up + $this->postCommitCleanup($entity); + } + + /** + * @param null|object|object[] $entity + */ + private function postCommitCleanup($entity) : void + { $this->entityInsertions = $this->entityUpdates = $this->entityDeletions = $this->extraUpdates = - $this->entityChangeSets = $this->collectionUpdates = $this->collectionDeletions = $this->visitedCollections = - $this->scheduledForSynchronization = $this->orphanRemovals = []; + + if (null === $entity) { + $this->entityChangeSets = $this->scheduledForSynchronization = []; + + return; + } + + $entities = \is_object($entity) + ? [$entity] + : $entity; + + foreach ($entities as $object) { + $oid = \spl_object_hash($object); + + $this->clearEntityChangeSet($oid); + + unset($this->scheduledForSynchronization[$this->em->getClassMetadata(\get_class($object))->rootEntityName][$oid]); + } } /** @@ -3101,7 +3124,7 @@ class UnitOfWork implements PropertyChangedListener */ public function clearEntityChangeSet($oid) { - $this->entityChangeSets[$oid] = []; + unset($this->entityChangeSets[$oid]); } /* PropertyChangedListener implementation */ diff --git a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php index ff025df4f..bfad30be8 100644 --- a/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php +++ b/tests/Doctrine/Tests/ORM/UnitOfWorkTest.php @@ -163,7 +163,8 @@ class UnitOfWorkTest extends OrmTestCase $this->_unitOfWork->persist($entity); $this->_unitOfWork->commit(); - $this->assertEquals(1, count($persister->getInserts())); + $this->assertCount(1, $persister->getInserts()); + $persister->reset(); $this->assertTrue($this->_unitOfWork->isInIdentityMap($entity)); @@ -360,6 +361,49 @@ class UnitOfWorkTest extends OrmTestCase $this->assertFalse($this->_unitOfWork->isScheduledForInsert($entity2)); } + /** + * @group #5579 + */ + public function testEntityChangeSetIsNotClearedAfterFlushOnSingleEntity() : void + { + $entity1 = new NotifyChangedEntity; + $entity2 = new NotifyChangedEntity; + + $entity1->setData('thedata'); + $entity2->setData('thedata'); + + $this->_unitOfWork->persist($entity1); + $this->_unitOfWork->persist($entity2); + + $this->_unitOfWork->commit($entity1); + self::assertEmpty($this->_unitOfWork->getEntityChangeSet($entity1)); + self::assertCount(1, $this->_unitOfWork->getEntityChangeSet($entity2)); + } + + /** + * @group #5579 + */ + public function testEntityChangeSetIsNotClearedAfterFlushOnArrayOfEntities() : void + { + $entity1 = new NotifyChangedEntity; + $entity2 = new NotifyChangedEntity; + $entity3 = new NotifyChangedEntity; + + $entity1->setData('thedata'); + $entity2->setData('thedata'); + $entity3->setData('thedata'); + + $this->_unitOfWork->persist($entity1); + $this->_unitOfWork->persist($entity2); + $this->_unitOfWork->persist($entity3); + + $this->_unitOfWork->commit([$entity1, $entity3]); + + self::assertEmpty($this->_unitOfWork->getEntityChangeSet($entity1)); + self::assertEmpty($this->_unitOfWork->getEntityChangeSet($entity3)); + self::assertCount(1, $this->_unitOfWork->getEntityChangeSet($entity2)); + } + /** * Data Provider *