You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using Class Table Inheritance (CTI) with predefined IDs (e.g., from an external system) for internal representation, retrieving an entity via the parent class and then the child class causes an identity map collision. Doctrine creates a new instance instead of reusing the managed one, resulting in duplicate instances with the same ID in the Unit of Work.
Steps to Reproduce
Set up a CTI hierarchy with BaseEntity (parent) and ChildEntityA (child), using a predefined/external string ID.
Persist a ChildEntityA instance with a predefined ID.
Fetch it via $em->find(BaseEntity::class, $externalId) – returns ChildEntityA.
Fetch it via $em->find(ChildEntityA::class, $externalId) – creates a new instance.
Call $em->flush(), which triggers an identity collision.
Expected Behavior
The second find() should return the existing managed instance from the UOW, even with predefined/external IDs.
Actual Behavior
A new instance is created, causing an identity collision. This occurs specifically when using predefined IDs.
Environment
composer show -i | grep doctrine
beberlei/doctrineextensions 1.5.0 A set of extensions to Doctrine 2 that add support for additional query functions available in MySQL, Oracle, PostgreSQL and SQLite.
dama/doctrine-test-bundle 8.3.0 Symfony bundle to isolate doctrine database tests and improve test performance
doctrine/cache 2.2.0 PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.
doctrine/collections 2.2.2 PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.
doctrine/common 3.5.0 PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, p...
doctrine/data-fixtures 2.0.2 Data Fixtures for all Doctrine Object Managers
doctrine/dbal 3.9.4 Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.
doctrine/deprecations 1.1.4 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.
doctrine/doctrine-bundle 2.13.2 Symfony DoctrineBundle
doctrine/doctrine-fixtures-bundle 3.7.1 Symfony DoctrineFixturesBundle
doctrine/doctrine-migrations-bundle 3.4.1 Symfony DoctrineMigrationsBundle
doctrine/event-manager 2.0.1 The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.
doctrine/inflector 2.0.10 PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.
doctrine/instantiator 2.0.0 A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer 3.0.1 PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.
doctrine/migrations 3.8.2 PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easi...
doctrine/orm 3.3.2 Object-Relational-Mapper for PHP
doctrine/persistence 3.4.0 The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.
doctrine/sql-formatter 1.5.2 a PHP SQL highlighting library
dunglas/doctrine-json-odm 1.4.2 An object document mapper for Doctrine ORM using JSON types of modern RDBMS.
gedmo/doctrine-extensions 3.19.0 Doctrine behavioral extensions
phpstan/phpstan-doctrine 1.5.7 Doctrine extensions for PHPStan
scienta/doctrine-json-functions 6.3.0 A set of extensions to Doctrine that add support for json query functions.
simpod/doctrine-utcdatetime 0.3.0 Doctrine UTC DateTime
stof/doctrine-extensions-bundle 1.13.0 Integration of the gedmo/doctrine-extensions with Symfony
symfony/doctrine-bridge 7.2.4 Provides integration for Doctrine with various Symfony components
Using latest stable symfony 7.2.4
Using Api Platform: 3.4.16
Percona MySQL Database: 8.0.36
PHP: 8.3.17 under alpine linux
Reproducible Example
<?phpuseDoctrine\ORM\MappingasORM;
// Parent entity with predefined ID
#[ORM\Entity]
#[ORM\InheritanceType('JOINED')]
#[ORM\DiscriminatorColumn(name: 'type', type: 'string')]
#[ORM\DiscriminatorMap(['a' => ChildEntityA::class])]
class BaseEntity {
#[ORM\Id]
#[ORM\Column(type: 'string')] // Predefined/external IDprotected$id;
publicfunctionsetId($id) { $this->id = $id; }
publicfunctiongetId() { return$this->id; }
}
// Child entity
#[ORM\Entity]
class ChildEntityA extends BaseEntity {
#[ORM\Column(type: 'string)] private $fieldA; public function setFieldA($value) { $this->fieldA = $value; } public function getFieldA() { return $this->fieldA; }}// Reproduce the issue$em = // Your EntityManager setup$externalId = 'external-123'; // Predefined/external ID// Create and persist entity$entity = newChildEntityA();
$entity->setId($externalId);
$entity->setFieldA('test');
$em->persist($entity);
$em->flush();
// Fetch via parent class$baseEntity = $em->find(BaseEntity::class, $externalId); // Returns ChildEntityA// Fetch via child class$childEntity = $em->find(ChildEntityA::class, $externalId); // New instance created// Check if they’re the samevar_dump($baseEntity === $childEntity); // Outputs: false// Trigger collision$em->flush(); // Throws identity collision error
Additional Notes
This seems related to how the UOW manages identity mapping for CTI with predefined/external IDs when querying child classes directly.
The text was updated successfully, but these errors were encountered:
juslintek
changed the title
Identity Map Collision with Class Table Inheritance When Using Predefined/External IDs for Internal Representation
Identity Map Collision with Class Table Inheritance When Using Predefined IDs
Mar 7, 2025
Description
When using Class Table Inheritance (CTI) with predefined IDs (e.g., from an external system) for internal representation, retrieving an entity via the parent class and then the child class causes an identity map collision. Doctrine creates a new instance instead of reusing the managed one, resulting in duplicate instances with the same ID in the Unit of Work.
Steps to Reproduce
BaseEntity
(parent) andChildEntityA
(child), using a predefined/external string ID.ChildEntityA
instance with a predefined ID.$em->find(BaseEntity::class, $externalId)
– returnsChildEntityA
.$em->find(ChildEntityA::class, $externalId)
– creates a new instance.$em->flush()
, which triggers an identity collision.Expected Behavior
The second
find()
should return the existing managed instance from the UOW, even with predefined/external IDs.Actual Behavior
A new instance is created, causing an identity collision. This occurs specifically when using predefined IDs.
Environment
Using latest stable symfony 7.2.4
Using Api Platform: 3.4.16
Percona MySQL Database: 8.0.36
PHP: 8.3.17 under alpine linux
Reproducible Example
Additional Notes
This seems related to how the UOW manages identity mapping for CTI with predefined/external IDs when querying child classes directly.
The text was updated successfully, but these errors were encountered: