QueryBuilder does not work with UUID in MySQL 8 #7029

Closed
opened 2026-01-22 15:43:23 +01:00 by admin · 5 comments
Owner

Originally created by @krstns on GitHub (Aug 30, 2022).

BuMySQLort

As per: https://stackoverflow.com/questions/73530182/how-to-properly-use-uuid-with-doctrine-when-using-mysql-database
QueryBuilder does not mysql 8 uuid implementation.

Q A
BC Break no
Version 2.12.3

Summary

After deploying a project on MySQL 8 database instead of Postgres 13 as usual we found some functionality broken - when filtering was used the data was not retrieved from the database even though full lists and single items were retrieved ok.
After closer analysis we have found that retrieving entities using UUID passed as string does not work when a QueryBuilder was used instead of a simple find or findBy call.

Current behavior

Using string with entity UUID in query builder does not work when the id is of type UUID in the MySQL 8 database, while it works fine with Postgres 13/14.

How to reproduce

Given:

#[ORM\Entity]
#[ORM\Table(name: 'abc')]
class Abc {
    /**
     * @var Uuid|null The id 
     */
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: "doctrine.uuid_generator")]
    #[ORM\Column(name: 'abc_id', type: 'uuid', unique: true)]
    private ?Uuid $id;

    public function getId(): ?Uuid {
        return $this->id;
    }


    /**
     * @var Abd 
     */
    #[ORM\ManyToOne(targetEntity: Abd::class)]
    #[ORM\JoinColumn(name: "abc_abd_id", referencedColumnName: "abd_id", nullable: false)]
    public Abd $abd;
}

#[ORM\Entity]
#[ORM\Table(name: 'abd')]
class Abd {
    /**
     * @var Uuid|null The id 
     */
    #[ORM\Id]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: "doctrine.uuid_generator")]
    #[ORM\Column(name: 'abd_id', type: 'uuid', unique: true)]
    private ?Uuid $id;

    public function getId(): ?Uuid {
        return $this->id;
    }

    /**
     * @var string Name
     */
    #[ORM\Column(name: 'abd_name')]
    public $name;

}

calling:

$abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]);
assert($abd != null);
$entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c')
    ->andWhere('c.abd = :abd')
    ->setParameter('abd', $abd)
    ->getQuery()
    ->execute();

will fail, but:

$abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]);
assert($abd != null);
$entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c')
    ->andWhere('c.abd = :abd')
    ->setParameter('abd', $abd->getId()->toBinary())
    ->getQuery()
    ->execute();

will work.

Expected behavior

$abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]);
assert($abd != null);
$entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c')
    ->andWhere('c.abd = :abd')
    ->setParameter('abd', $abd)
    ->getQuery()
    ->execute();

Should work in MySQL 8 in the same way as it does in Postgres 13/14.

Originally created by @krstns on GitHub (Aug 30, 2022). ### BuMySQLort As per: https://stackoverflow.com/questions/73530182/how-to-properly-use-uuid-with-doctrine-when-using-mysql-database QueryBuilder does not mysql 8 uuid implementation. | Q | A |------------ | ------ | BC Break | no | Version | 2.12.3 #### Summary After deploying a project on MySQL 8 database instead of Postgres 13 as usual we found some functionality broken - when filtering was used the data was not retrieved from the database even though full lists and single items were retrieved ok. After closer analysis we have found that retrieving entities using UUID passed as string does not work when a QueryBuilder was used instead of a simple `find` or `findBy` call. #### Current behavior Using string with entity UUID in query builder does not work when the id is of type UUID in the MySQL 8 database, while it works fine with Postgres 13/14. #### How to reproduce Given: ``` #[ORM\Entity] #[ORM\Table(name: 'abc')] class Abc { /** * @var Uuid|null The id */ #[ORM\Id] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator(class: "doctrine.uuid_generator")] #[ORM\Column(name: 'abc_id', type: 'uuid', unique: true)] private ?Uuid $id; public function getId(): ?Uuid { return $this->id; } /** * @var Abd */ #[ORM\ManyToOne(targetEntity: Abd::class)] #[ORM\JoinColumn(name: "abc_abd_id", referencedColumnName: "abd_id", nullable: false)] public Abd $abd; } #[ORM\Entity] #[ORM\Table(name: 'abd')] class Abd { /** * @var Uuid|null The id */ #[ORM\Id] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator(class: "doctrine.uuid_generator")] #[ORM\Column(name: 'abd_id', type: 'uuid', unique: true)] private ?Uuid $id; public function getId(): ?Uuid { return $this->id; } /** * @var string Name */ #[ORM\Column(name: 'abd_name')] public $name; } ``` calling: ``` $abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]); assert($abd != null); $entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c') ->andWhere('c.abd = :abd') ->setParameter('abd', $abd) ->getQuery() ->execute(); ``` will fail, but: ``` $abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]); assert($abd != null); $entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c') ->andWhere('c.abd = :abd') ->setParameter('abd', $abd->getId()->toBinary()) ->getQuery() ->execute(); ``` will work. #### Expected behavior ``` $abd = $entityManager->getRepository(VeterinaryClinic::class)->findOneBy(["name" => "test"]); assert($abd != null); $entities = $entityManager->getRepository(Abc::class)->createQueryBuilder('c') ->andWhere('c.abd = :abd') ->setParameter('abd', $abd) ->getQuery() ->execute(); ``` Should work in MySQL 8 in the same way as it does in Postgres 13/14.
admin closed this issue 2026-01-22 15:43:23 +01:00
Author
Owner

@derrabus commented on GitHub (Aug 30, 2022):

    private ?Uuid $id;

Which Uuid class is this?

@derrabus commented on GitHub (Aug 30, 2022): > ```php > private ?Uuid $id; > ``` Which `Uuid` class is this?
Author
Owner

@krstns commented on GitHub (Aug 30, 2022):

private ?Uuid $id;


    
      
    

      
    

    
  

Which Uuid class is this?

sorry, forgot to add it, it's the Symfony Uuid:
Symfony\Component\Uid\Uuid

@krstns commented on GitHub (Aug 30, 2022): > ``` > ``` > private ?Uuid $id; > ``` > > > > > > > > > > > > > Which Uuid class is this? > ``` sorry, forgot to add it, it's the Symfony Uuid: `Symfony\Component\Uid\Uuid`
Author
Owner

@derrabus commented on GitHub (Aug 30, 2022):

Please open a bug at https://github.com/symfony/symfony then.

@derrabus commented on GitHub (Aug 30, 2022): Please open a bug at https://github.com/symfony/symfony then.
Author
Owner

@krstns commented on GitHub (Aug 30, 2022):

@derrabus will do. Since I don't know the inner workings of the QueryBuilder, I thought that if passing reference to an entity works for Postgres it would also work for MySQL.

@krstns commented on GitHub (Aug 30, 2022): @derrabus will do. Since I don't know the inner workings of the QueryBuilder, I thought that if passing reference to an entity works for Postgres it would also work for MySQL.
Author
Owner

@mhitza commented on GitHub (Oct 31, 2023):

@krstns have you created an upstream ticket for this issue (couldn't easily find one)?

Encountering something similar when using a findBy(['id' => ['uuid..', 'uuid...']), when following the official symfony documentation and this boilerplate code

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;

class User implements UserInterface
{
    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME, unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
    private ?Uuid $id;

    public function getId(): ?Uuid
    {
        return $this->id;
    }

    // ...
}

note: for reference I'm working around this issue by reencoding the UUID strings ids to binary by mapping Uuid::fromString($id)->toBinary()

@derrabus what is the recommended approach, if the symfony UUID component is no supported by Doctrine, when one wants to use UUID's for entity primary keys?

@mhitza commented on GitHub (Oct 31, 2023): @krstns have you created an upstream ticket for this issue (couldn't easily find one)? Encountering something similar when using a `findBy(['id' => ['uuid..', 'uuid...'])`, when following the official symfony documentation and this boilerplate code ```php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Types\UuidType; use Symfony\Component\Uid\Uuid; class User implements UserInterface { #[ORM\Id] #[ORM\Column(type: UuidType::NAME, unique: true)] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')] private ?Uuid $id; public function getId(): ?Uuid { return $this->id; } // ... } ``` note: for reference I'm working around this issue by reencoding the UUID strings ids to binary by mapping `Uuid::fromString($id)->toBinary()` @derrabus what is the recommended approach, if the symfony UUID component is no supported by Doctrine, when one wants to use UUID's for entity primary keys?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7029