Bug: Hardcoded 'id' property in ManyToMany association logic causes crash in non-standard identifier setups
Environment
| Package/Software |
Version |
| sonata-project/entity-audit-bundle |
1.23.1 |
| PHP |
8.4.0 |
| Doctrine ORM |
2.20.13 |
| Framework |
Neos Flow 8.4.2 (Standalone) |
Subject
In the AuditReader.php class, the logic for handling ManyToMany relationships (both owning and inverse sides) assumes that the primary key of an entity is always a property named exactly id. It calls $classMetadata->getFieldValue($entity, 'id') directly.
In environments like Neos Flow, entities typically use UUIDs for primary keys which are mapped to internal properties (e.g., Persistence_Object_Identifier) and do not have a PHP property named $id.
When AuditReader attempts to fetch the identifier value, Doctrine ORM 2.20.13 throws a warning because the key "id" is missing from the class metadata:
Warning: Undefined array key "id" in .../doctrine/orm/src/Mapping/ClassMetadataInfo.php
The library should instead use the Doctrine metadata API to determine the identifier field name dynamically.
Steps to reproduce
- Use an entity where the primary key property is NOT named
$id (e.g., any Neos Flow entity or an entity with a custom $uuid primary key).
- Create a ManyToMany relationship between two audited entities.
- Call
AuditReader::getEntityHistory() or AuditReader::find() on the entity.
- The code enters the ManyToMany resolution block inside
createEntity() and triggers the warning.
Expected results
The AuditReader should be framework-agnostic. It should query $classMetadata->getIdentifierFieldNames() to find the correct property name for the identifier instead of assuming it is called 'id'.
Actual results
Warning: Undefined array key "id" in /var/www/localdev/.../Packages/Libraries/doctrine/orm/src/Mapping/ClassMetadataInfo.php line 936
Because the value returned is null (due to the undefined key), the resulting SQL queries for the audit relationship tables are corrupted.
Suggested Fix
In src/AuditReader.php, replace the hardcoded 'id' string with a dynamic lookup from the metadata.
Location 1 (Around line 1024, Owning Side of ManyToMany):
// Change:
$values[] = $classMetadata->getFieldValue($entity, 'id');
// To:
$identifierFieldNames = $classMetadata->getIdentifierFieldNames();
$values[] = $classMetadata->getFieldValue($entity, $identifierFieldNames[0]);
Location 2 (Around line 1109, Inverse Side of ManyToMany):
// Change:
$values[] = $classMetadata->getFieldValue($entity, 'id');
// To:
$identifierFieldNames = $classMetadata->getIdentifierFieldNames();
$values[] = $classMetadata->getFieldValue($entity, $identifierFieldNames[0]);
Note: While many Symfony projects use $id by convention, using the metadata API is the correct "Doctrine way" to handle identifiers and ensures the bundle works across different frameworks and naming conventions.
Bug: Hardcoded 'id' property in ManyToMany association logic causes crash in non-standard identifier setups
Environment
Subject
In the
AuditReader.phpclass, the logic for handling ManyToMany relationships (both owning and inverse sides) assumes that the primary key of an entity is always a property named exactlyid. It calls$classMetadata->getFieldValue($entity, 'id')directly.In environments like Neos Flow, entities typically use UUIDs for primary keys which are mapped to internal properties (e.g.,
Persistence_Object_Identifier) and do not have a PHP property named$id.When
AuditReaderattempts to fetch the identifier value, Doctrine ORM 2.20.13 throws a warning because the key "id" is missing from the class metadata:Warning: Undefined array key "id" in .../doctrine/orm/src/Mapping/ClassMetadataInfo.phpThe library should instead use the Doctrine metadata API to determine the identifier field name dynamically.
Steps to reproduce
$id(e.g., any Neos Flow entity or an entity with a custom$uuidprimary key).AuditReader::getEntityHistory()orAuditReader::find()on the entity.createEntity()and triggers the warning.Expected results
The
AuditReadershould be framework-agnostic. It should query$classMetadata->getIdentifierFieldNames()to find the correct property name for the identifier instead of assuming it is called'id'.Actual results
Because the value returned is
null(due to the undefined key), the resulting SQL queries for the audit relationship tables are corrupted.Suggested Fix
In
src/AuditReader.php, replace the hardcoded'id'string with a dynamic lookup from the metadata.Location 1 (Around line 1024, Owning Side of ManyToMany):
Location 2 (Around line 1109, Inverse Side of ManyToMany):
Note: While many Symfony projects use
$idby convention, using the metadata API is the correct "Doctrine way" to handle identifiers and ensures the bundle works across different frameworks and naming conventions.