Skip to content

Commit e71868f

Browse files
authored
Merge pull request #10968 from greg0ire/reject-id-collisions-unconditionally
Reject ID collisions in identity map unconditionally
2 parents 46ef989 + 795e773 commit e71868f

File tree

5 files changed

+20
-56
lines changed

5 files changed

+20
-56
lines changed

UPGRADE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Upgrade to 3.0
22

3+
## BC BREAK: collisions in identity map are unconditionally rejected
4+
5+
`Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap()` and
6+
`Doctrine\ORM\Configuration::isRejectIdCollisionInIdentityMapEnabled()` are now
7+
no-ops and will be deprecated in 3.1.0.
8+
39
## BC BREAK: Lifecycle callback mapping on embedded classes is now explicitly forbidden
410

511
Lifecycle callback mapping on embedded classes produced no effect, and is now

lib/Doctrine/ORM/Configuration.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,13 +605,24 @@ public function setLazyGhostObjectEnabled(bool $flag): void
605605
$this->attributes['isLazyGhostObjectEnabled'] = $flag;
606606
}
607607

608+
/** To be deprecated in 3.1.0 */
608609
public function setRejectIdCollisionInIdentityMap(bool $flag): void
609610
{
610-
$this->attributes['rejectIdCollisionInIdentityMap'] = $flag;
611+
if (! $flag) {
612+
throw new LogicException(<<<'EXCEPTION'
613+
Rejecting ID collisions in the identity map cannot be disabled anymore.
614+
Please remove the call to setRejectIdCollisionInIdentityMap(false).
615+
EXCEPTION);
616+
}
611617
}
612618

619+
/**
620+
* To be deprecated in 3.1.0
621+
*
622+
* @return true
623+
*/
613624
public function isRejectIdCollisionInIdentityMapEnabled(): bool
614625
{
615-
return $this->attributes['rejectIdCollisionInIdentityMap'] ?? false;
626+
return true;
616627
}
617628
}

lib/Doctrine/ORM/UnitOfWork.php

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,38 +1485,7 @@ public function addToIdentityMap(object $entity): bool
14851485

14861486
if (isset($this->identityMap[$className][$idHash])) {
14871487
if ($this->identityMap[$className][$idHash] !== $entity) {
1488-
if ($this->em->getConfiguration()->isRejectIdCollisionInIdentityMapEnabled()) {
1489-
throw EntityIdentityCollisionException::create($this->identityMap[$className][$idHash], $entity, $idHash);
1490-
}
1491-
1492-
Deprecation::trigger(
1493-
'doctrine/orm',
1494-
'https://github.com/doctrine/orm/pull/10785',
1495-
<<<'EXCEPTION'
1496-
While adding an entity of class %s with an ID hash of "%s" to the identity map,
1497-
another object of class %s was already present for the same ID. This will trigger
1498-
an exception in ORM 3.0.
1499-
1500-
IDs should uniquely map to entity object instances. This problem may occur if:
1501-
1502-
- you use application-provided IDs and reuse ID values;
1503-
- database-provided IDs are reassigned after truncating the database without
1504-
clearing the EntityManager;
1505-
- you might have been using EntityManager#getReference() to create a reference
1506-
for a nonexistent ID that was subsequently (by the RDBMS) assigned to another
1507-
entity.
1508-
1509-
Otherwise, it might be an ORM-internal inconsistency, please report it.
1510-
1511-
To opt-in to the new exception, call
1512-
\Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap on the entity
1513-
manager's configuration.
1514-
EXCEPTION
1515-
,
1516-
get_class($entity),
1517-
$idHash,
1518-
get_class($this->identityMap[$className][$idHash]),
1519-
);
1488+
throw EntityIdentityCollisionException::create($this->identityMap[$className][$idHash], $entity, $idHash);
15201489
}
15211490

15221491
return false;

tests/Doctrine/Tests/ORM/Functional/BasicFunctionalTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,8 +1079,6 @@ public function testWrongAssociationInstance(): void
10791079

10801080
public function testItThrowsWhenReferenceUsesIdAssignedByDatabase(): void
10811081
{
1082-
$this->_em->getConfiguration()->setRejectIdCollisionInIdentityMap(true);
1083-
10841082
$user = new CmsUser();
10851083
$user->name = 'test';
10861084
$user->username = 'test';

tests/Doctrine/Tests/ORM/UnitOfWorkTest.php

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -628,28 +628,8 @@ public function testRemovedEntityIsRemovedFromOneToManyCollection(): void
628628
self::assertEmpty($user->phonenumbers->getSnapshot());
629629
}
630630

631-
public function testItTriggersADeprecationNoticeWhenApplicationProvidedIdsCollide(): void
632-
{
633-
// We're using application-provided IDs and assign the same ID twice
634-
// Note this is about colliding IDs in the identity map in memory.
635-
// Duplicate database-level IDs would be spotted when the EM is flushed.
636-
637-
$phone1 = new CmsPhonenumber();
638-
$phone1->phonenumber = '1234';
639-
$this->_unitOfWork->persist($phone1);
640-
641-
$phone2 = new CmsPhonenumber();
642-
$phone2->phonenumber = '1234';
643-
644-
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/orm/pull/10785');
645-
646-
$this->_unitOfWork->persist($phone2);
647-
}
648-
649631
public function testItThrowsWhenApplicationProvidedIdsCollide(): void
650632
{
651-
$this->_emMock->getConfiguration()->setRejectIdCollisionInIdentityMap(true);
652-
653633
// We're using application-provided IDs and assign the same ID twice
654634
// Note this is about colliding IDs in the identity map in memory.
655635
// Duplicate database-level IDs would be spotted when the EM is flushed.

0 commit comments

Comments
 (0)