Wrong column order in inherited table metadata #5576

Open
opened 2026-01-22 15:11:46 +01:00 by admin · 0 comments
Owner

Originally created by @mpajunen on GitHub (Jun 15, 2017).

We ran into an issue where the column and parameter order of an insert statement for a new entity don't match. Something like this:

INSERT INTO Person (name, group_id, email) 
VALUES ("John Smith", "john@example.org", 3)

(I might be able to add a failing test case later, but thought I'd report this now in case there's a straightforward way to fix the problem.)

The issue occurs when using Class Table Inheritance and metadata cache. As far as I can tell the problem is that field order of the ClassMetadataInfo reflFields property is unstable.

Without cache:

  1. AbstractClassMetadataFactory loads the metadata directly if metadata is not found in the cache or if cache is not enabled.
  2. AbstractClassMetadataFactory calls the load implementation for each class in the inheritance hierarchy.
  3. ClassMetadataFactory handles inherited fields, relations and embeds and adds them to reflFields.
  4. When ClassMetadataInfo::wakeupReflection is finally called, reflFields already includes the super class properties.
  5. The child class properties are added: first embeds, then fields and finally associations.

When metadata is found in cache:

  1. ClassMetadataInfo::wakeupReflection is called immediately and reflFields is always empty.
  2. Now all embeds, fields and associations from the entire hierarchy are added to reflFields.

Insert statement columns always follow the non-cache order. It might be that just handling embeds, fields and relations in the same order everywhere would be enough to fix the problem.

Originally created by @mpajunen on GitHub (Jun 15, 2017). We ran into an issue where the column and parameter order of an insert statement for a new entity don't match. Something like this: ``` INSERT INTO Person (name, group_id, email) VALUES ("John Smith", "john@example.org", 3) ``` (I might be able to add a failing test case later, but thought I'd report this now in case there's a straightforward way to fix the problem.) The issue occurs when using Class Table Inheritance and metadata cache. As far as I can tell the problem is that field order of the `ClassMetadataInfo` `reflFields` property is unstable. Without cache: 1. `AbstractClassMetadataFactory` loads the metadata directly if [metadata is not found in the cache](https://github.com/doctrine/common/blob/7181fafc832e90e866000b7cbe86aa0939cf2de0/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php#L217) or if [cache is not enabled](https://github.com/doctrine/common/blob/7181fafc832e90e866000b7cbe86aa0939cf2de0/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php#L226). 2. `AbstractClassMetadataFactory` [calls the load implementation](https://github.com/doctrine/common/blob/7181fafc832e90e866000b7cbe86aa0939cf2de0/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php#L333) for each class in the inheritance hierarchy. 3. `ClassMetadataFactory` handles inherited [fields](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L130), [relations](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L131) and [embeds](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L132) and [adds them to `reflFields`](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php#L413). 4. When [`ClassMetadataInfo::wakeupReflection`](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L922) is [finally called](https://github.com/doctrine/common/blob/7181fafc832e90e866000b7cbe86aa0939cf2de0/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php#L344), `reflFields` already includes the super class properties. 5. The child class properties are added: first [embeds](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L930), then [fields](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L953) and finally [associations](https://github.com/doctrine/doctrine2/blob/fc67b398a1efd3d61837778e2cda2d05a395778c/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php#L968). When metadata is found in cache: 1. `ClassMetadataInfo::wakeupReflection` is [called immediately](https://github.com/doctrine/common/blob/7181fafc832e90e866000b7cbe86aa0939cf2de0/lib/Doctrine/Common/Persistence/Mapping/AbstractClassMetadataFactory.php#L215) and `reflFields` is always empty. 2. Now all embeds, fields and associations from the entire hierarchy are added to `reflFields`. Insert statement columns always follow the non-cache order. It might be that just handling embeds, fields and relations in the same order everywhere would be enough to fix the problem.
admin added the BugMissing Tests labels 2026-01-22 15:11:46 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5576