From bac6570af1e08d2425d0b527e630afb994bede49 Mon Sep 17 00:00:00 2001 From: nclavaud Date: Tue, 17 Mar 2015 22:29:10 +0100 Subject: [PATCH] Update identityMap when entity gets managed again http://www.doctrine-project.org/jira/browse/DDC-3619 When using SoftDeleteable doctrine extension, an entity can be scheduled for deletion, then persisted before flushing. In such a case, the entity was removed from the unit of work identity map and no reference was hold. This could lead to spl_object_hash collisions, and prevent another, new entity to be persisted later. This fix makes sure the unit of work identity map holds a reference to the entity after it has been soft-deleted. --- lib/Doctrine/ORM/UnitOfWork.php | 1 + .../ORM/Functional/Ticket/DDC3619Test.php | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3619Test.php diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index b36ad7fb8..fd7f69cc5 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -1630,6 +1630,7 @@ class UnitOfWork implements PropertyChangedListener case self::STATE_REMOVED: // Entity becomes managed again unset($this->entityDeletions[$oid]); + $this->addToIdentityMap($entity); $this->entityStates[$oid] = self::STATE_MANAGED; break; diff --git a/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3619Test.php b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3619Test.php new file mode 100644 index 000000000..2d22c907c --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/Ticket/DDC3619Test.php @@ -0,0 +1,46 @@ +_schemaTool->createSchema( + array( + $this->_em->getClassMetadata(__NAMESPACE__ . '\DDC3619Entity'), + ) + ); + } + + public function testIssue() + { + $uow = $this->_em->getUnitOfWork(); + + $entity = new DDC3619Entity(); + $this->_em->persist($entity); + $this->_em->flush(); + $this->assertTrue($uow->isInIdentityMap($entity)); + + $this->_em->remove($entity); + $this->assertFalse($uow->isInIdentityMap($entity)); + + $this->_em->persist($entity); + $this->assertTrue($uow->isInIdentityMap($entity)); + } +} + +/** + * @Entity() + */ +class DDC3619Entity +{ + /** + * @Id + * @Column(type="integer") + * @GeneratedValue(strategy="IDENTITY") + */ + protected $id; +}