Skip to content

Bug: Hardcoded 'id' property in ManyToMany association logic causes crash in non-standard identifier setups #682

Description

@anastasdimitriadou-cpu

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

  1. 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).
  2. Create a ManyToMany relationship between two audited entities.
  3. Call AuditReader::getEntityHistory() or AuditReader::find() on the entity.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions