PersistentCollection uses Ulid Rfc4122 as indexBy value instead of uid one #7062

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

Originally created by @ndousson on GitHub (Oct 18, 2022).

Bug Report

Q A
BC Break no
Version 2.13.2 (Symfony 6.1.x)

Summary

During our developments, we encounter a problem with the key index value of PersistentCollection when using a Ulid typed property.

When we executes a find(), Doctrine hydrates correctly the Ulid value of the object in the Collection but use the Rfc4122 Ulid value format as the index.

We expect the same value at the one in the entity.

I previously opened an issue on the Symfony repository => https://github.com/symfony/symfony/issues/47867

Thanks to @stof and @fancyweb for their feedback, the issue should be opened here.

Current behavior

How to reproduce

  1. Create a new SF project
  2. Require the following dependencies:
    • composer require symfony/orm-pack
    • composer require --dev symfony/maker-bundle
    • composer require symfony/uid
  3. Create 2 entities (code example below):
    • Container
    • Item
  4. Load 1 container + 2 related item in DB (I use DoctrineFixtures locally to reproduce)
  5. Execute the following command:
symfony console doctrine:query:dql "SELECT c FROM App\Entity\Container c WHERE c.id = 1" --depth=3
  1. The result look like this:
array(1) {
  [0]=>
  object(stdClass)#311 (3) {
    ["__CLASS__"]=>
    string(20) "App\Entity\Container"
    ["id:App\Entity\Container:private"]=>
    int(1)
    ["items:App\Entity\Container:private"]=>
    array(2) {
      ["0183d58a-e396-fe56-92bd-a4efa8780329"]=>
      string(15) "App\Entity\Item"
      ["0183d58a-e396-fe56-92bd-a4efa878032a"]=>
      string(15) "App\Entity\Item"
    }
  }
}

Example of code:

<?php

namespace App\Entity;

use App\Repository\ContainerRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: ContainerRepository::class)]
class Container
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\OneToMany(mappedBy: 'container', targetEntity: Item::class, cascade: ['PERSIST'], fetch: 'EAGER', orphanRemoval: true, indexBy: 'identifier')]
    private Collection $items;

    public function __construct()
    {
        $this->items = new ArrayCollection();
    }

    // ... getter/setter methods
}
<?php

namespace App\Entity;

use App\Repository\ItemRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Uid\Ulid;

#[ORM\Entity(repositoryClass: ItemRepository::class)]
class Item
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(type: 'ulid')]
    private ?Ulid $identifier = null;

    #[ORM\ManyToOne(inversedBy: 'items')]
    #[ORM\JoinColumn(nullable: false)]
    private ?Container $container = null;

    public function __construct()
    {
        $this->identifier = new Ulid();
    }

    // ... getter/setter methods
}

Expected behavior

As a "logic" behavior, we expect to have the uid value of the Ulid and not the Rfc4122 as the index key of the collection.

Additional Context

Output of debug() on repository find() result:

^ App\Entity\Container^ {#312
  -id: 1
  -items: Doctrine\ORM\PersistentCollection^ {#177
    #collection: Doctrine\Common\Collections\ArrayCollection^ {#237
      -elements: array:2 [
        "0183d58a-e396-fe56-92bd-a4efa8780329" => App\Entity\Item^ {#218
          -id: 1
          -identifier: Symfony\Component\Uid\Ulid^ {#306
            #uid: "01GFARNRWPZSB95FD4XYM7G0S9"
            toBase58: "1BrKjxuER3mmEp2kaZh2uW"
            toRfc4122: "0183d58a-e396-fe56-92bd-a4efa8780329"
            time: "2022-10-14 08:09:52.790 UTC"
          }
          -container: App\Entity\Container^ {#312}
        }
        "0183d58a-e396-fe56-92bd-a4efa878032a" => App\Entity\Item^ {#216
          -id: 2
          -identifier: Symfony\Component\Uid\Ulid^ {#215
            #uid: "01GFARNRWPZSB95FD4XYM7G0SA"
            toBase58: "1BrKjxuER3mmEp2kaZh2uX"
            toRfc4122: "0183d58a-e396-fe56-92bd-a4efa878032a"
            time: "2022-10-14 08:09:52.790 UTC"
          }
          -container: App\Entity\Container^ {#312}
        }
      ]
    }
    #initialized: true
    -snapshot: array:2 [ …2]
    -owner: App\Entity\Container^ {#312}
    -association: array:16 [ …16]
    -em: Doctrine\ORM\EntityManager^ {#154 …11}
    -backRefFieldName: "container"
    -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#256 …}
    -isDirty: false
  }
}
Originally created by @ndousson on GitHub (Oct 18, 2022). ### Bug Report | Q | A |------------ | ------ | BC Break | no | Version | 2.13.2 (Symfony 6.1.x) #### Summary During our developments, we encounter a problem with the key index value of PersistentCollection when using a Ulid typed property. When we executes a find(), Doctrine hydrates correctly the Ulid value of the object in the Collection but use the Rfc4122 Ulid value format as the index. We expect the same value at the one in the entity. I previously opened an issue on the Symfony repository => https://github.com/symfony/symfony/issues/47867 Thanks to @stof and @fancyweb for their feedback, the issue should be opened here. #### Current behavior <!-- What is the current (buggy) behavior? --> #### How to reproduce 1. Create a new SF project 2. Require the following dependencies: - composer require symfony/orm-pack - composer require --dev symfony/maker-bundle - composer require symfony/uid 3. Create 2 entities (code example below): - Container - Item 4. Load 1 container + 2 related item in DB (I use DoctrineFixtures locally to reproduce) 5. Execute the following command: ```shell symfony console doctrine:query:dql "SELECT c FROM App\Entity\Container c WHERE c.id = 1" --depth=3 ``` 6. The result look like this: ```shell array(1) { [0]=> object(stdClass)#311 (3) { ["__CLASS__"]=> string(20) "App\Entity\Container" ["id:App\Entity\Container:private"]=> int(1) ["items:App\Entity\Container:private"]=> array(2) { ["0183d58a-e396-fe56-92bd-a4efa8780329"]=> string(15) "App\Entity\Item" ["0183d58a-e396-fe56-92bd-a4efa878032a"]=> string(15) "App\Entity\Item" } } } ``` --- Example of code: ```php <?php namespace App\Entity; use App\Repository\ContainerRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: ContainerRepository::class)] class Container { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\OneToMany(mappedBy: 'container', targetEntity: Item::class, cascade: ['PERSIST'], fetch: 'EAGER', orphanRemoval: true, indexBy: 'identifier')] private Collection $items; public function __construct() { $this->items = new ArrayCollection(); } // ... getter/setter methods } ``` ```php <?php namespace App\Entity; use App\Repository\ItemRepository; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Uid\Ulid; #[ORM\Entity(repositoryClass: ItemRepository::class)] class Item { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(type: 'ulid')] private ?Ulid $identifier = null; #[ORM\ManyToOne(inversedBy: 'items')] #[ORM\JoinColumn(nullable: false)] private ?Container $container = null; public function __construct() { $this->identifier = new Ulid(); } // ... getter/setter methods } ``` #### Expected behavior As a "logic" behavior, we expect to have the uid value of the Ulid and not the Rfc4122 as the index key of the collection. #### Additional Context Output of debug() on repository find() result: ```shell ^ App\Entity\Container^ {#312 -id: 1 -items: Doctrine\ORM\PersistentCollection^ {#177 #collection: Doctrine\Common\Collections\ArrayCollection^ {#237 -elements: array:2 [ "0183d58a-e396-fe56-92bd-a4efa8780329" => App\Entity\Item^ {#218 -id: 1 -identifier: Symfony\Component\Uid\Ulid^ {#306 #uid: "01GFARNRWPZSB95FD4XYM7G0S9" toBase58: "1BrKjxuER3mmEp2kaZh2uW" toRfc4122: "0183d58a-e396-fe56-92bd-a4efa8780329" time: "2022-10-14 08:09:52.790 UTC" } -container: App\Entity\Container^ {#312} } "0183d58a-e396-fe56-92bd-a4efa878032a" => App\Entity\Item^ {#216 -id: 2 -identifier: Symfony\Component\Uid\Ulid^ {#215 #uid: "01GFARNRWPZSB95FD4XYM7G0SA" toBase58: "1BrKjxuER3mmEp2kaZh2uX" toRfc4122: "0183d58a-e396-fe56-92bd-a4efa878032a" time: "2022-10-14 08:09:52.790 UTC" } -container: App\Entity\Container^ {#312} } ] } #initialized: true -snapshot: array:2 [ …2] -owner: App\Entity\Container^ {#312} -association: array:16 [ …16] -em: Doctrine\ORM\EntityManager^ {#154 …11} -backRefFieldName: "container" -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#256 …} -isDirty: false } } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7062