orm icon indicating copy to clipboard operation
orm copied to clipboard

Index property in #[ORM\Column] is not serialized in FieldMapping::__sleep()

Open kaskader201 opened this issue 4 months ago • 1 comments

Bug Report

Q A
Version 3.5.8
Previous Version if the bug is a regression unknown (likely since index was added to Column attribute)

Summary

The index property defined in #[ORM\Column(index: true)] is lost after metadata cache serialization because it's missing from the __sleep() method in FieldMapping class.

Current behavior

When using #[ORM\Column(index: true)] on an entity property, the index is correctly recognized during initial schema generation. However, after the metadata is cached and restored (e.g., after cache:clear), the index property becomes null, causing doctrine:schema:update --dump-sql to generate DROP INDEX statements for indexes that should exist according to the entity mapping.

Expected behavior

The index property should be preserved after metadata cache serialization/deserialization, and doctrine:schema:update should report no changes needed.

How to reproduce

  1. Create an entity with #[ORM\Column(index: true)]:

    <?php
    
    use Doctrine\DBAL\Types\Types;
    use Doctrine\ORM\Mapping as ORM;
    
    #[ORM\Entity]
    class Example
    {
        #[ORM\Id]
        #[ORM\GeneratedValue]
        #[ORM\Column]
        public int $id;
    
        #[ORM\Column(type: Types::INTEGER, index: true)]
        public int $someField;
    }
    
    
  • Run bin/console doctrine:cache:clear-metadata
  • Run bin/console doctrine:schema:update --force to create the table with index
  • Verify index exists: bin/console doctrine:schema:update --dump-sql → should show "Nothing to update"
  • Clear cache: bin/console cache:clear + bin/console doctrine:cache:clear-metadata
  • Run bin/console doctrine:schema:update --dump-sql

Actual result: Doctrine generates DROP INDEX idx_... for the index.

Expected result: "Nothing to update"

Root cause

In src/Mapping/FieldMapping.php, the __sleep() method defines which properties are serialized. The index property (defined on line 45) is missing from the boolean keys array on line 143:

 public function __sleep(): array
 {
     $serialized = ['type', 'fieldName', 'columnName'];

     // 'index' is MISSING from this array:
     foreach (['nullable', 'notInsertable', 'notUpdatable', 'id', 'unique', 'version', 'quoted'] as $boolKey) {
         if ($this->$boolKey) {
             $serialized[] = $boolKey;
         }
     }
     // ...
 }

Proposed fix

Add 'index' to the boolean keys array in __sleep():

 foreach (['nullable', 'notInsertable', 'notUpdatable', 'id', 'unique', 'version', 'quoted', 'index'] as $boolKey) {

Workaround

Use explicit #[ORM\Index] attribute on the entity class instead of index: true in #[ORM\Column]:

 #[ORM\Entity]
 #[ORM\Index(name: 'IDX_EXAMPLE_SOME_FIELD', columns: ['some_field'])]
 class Example
 {
     #[ORM\Column(type: Types::INTEGER)]
     public int $someField;
 }

kaskader201 avatar Dec 11 '25 22:12 kaskader201