Skip to content

Commit

Permalink
Add a safeguard against multiple objects competing for the same ident…
Browse files Browse the repository at this point in the history
…ity map entry
  • Loading branch information
mpdude committed Jun 22, 2023
1 parent 41f704c commit c4e2e84
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 2 deletions.
7 changes: 7 additions & 0 deletions lib/Doctrine/ORM/UnitOfWork.php
Original file line number Diff line number Diff line change
Expand Up @@ -1569,6 +1569,13 @@ public function addToIdentityMap($entity)
$className = $classMetadata->rootEntityName;

if (isset($this->identityMap[$className][$idHash])) {
if ($this->identityMap[$className][$idHash] !== $entity) {
throw new RuntimeException(sprintf(
'While adding an entity of class %s with an ID hash of "%s" to the identity map, another object was already present for the same ID. This exception is a safeguard against an internal inconsistency - IDs should uniquely map to entity object instances. This problam may occur if you create proxy instances directly using the ProxyFactory, instead of using \Doctrine\ORM\EntityManagerInterface::getReference(). Otherwise, it might be an ORM-internal inconsistency, please report it.',
$className,
$idHash
));
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function testEntityWithIdentifier(): void
*/
public function testProxyAsDqlParameterPersist(): void
{
$proxy = $this->_em->getProxyFactory()->getProxy(CmsUser::class, ['id' => $this->user->getId()]);
$proxy = $this->_em->getReference(CmsUser::class, ['id' => $this->user->getId()]);
$proxy->id = $this->user->getId();
$result = $this
->_em
Expand Down
2 changes: 1 addition & 1 deletion tests/Doctrine/Tests/ORM/Functional/Ticket/DDC1238Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public function testIssueProxyClear(): void

$user2 = $this->_em->getReference(DDC1238User::class, $userId);

$user->__load();
//$user->__load();

self::assertIsInt($user->getId(), 'Even if a proxy is detached, it should still have an identifier');

Expand Down
2 changes: 2 additions & 0 deletions tests/Doctrine/Tests/ORM/UnitOfWorkTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ protected function setUp(): void
$driverConnection = $this->createMock(Driver\Connection::class);
$driverConnection->method('prepare')
->willReturn($driverStatement);
$driverConnection->method('lastInsertId')
->willReturnOnConsecutiveCalls(1, 2, 3, 4, 5, 6);

$driver = $this->createMock(Driver::class);
$driver->method('getDatabasePlatform')
Expand Down

0 comments on commit c4e2e84

Please sign in to comment.