Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

My UUID config is as follows:

// config/packages/uid.yaml

framework:
    uid:
        default_uuid_version: 7
        time_based_uuid_version: 7

./bin/console debug:config framework uid outputs:

Current configuration for "framework.uid"
=========================================

default_uuid_version: 7
time_based_uuid_version: 7
enabled: true
name_based_uuid_version: 5

My entity has:

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

The auto-generated entity ID UUIDs are V6, not V7.

If I inspect any of the UUID primary keys in the database with:

./bin/console uuid:inspect 1eea7e0f-d006-64a2-9024-6b5706aaf847

It outputs:

----------------------- -------------------------------------- 
  Label                   Value                                 
 ----------------------- -------------------------------------- 
  Version                 6                                     
  toRfc4122 (canonical)   1eea7e0f-d006-64a2-9024-6b5706aaf847  
  toBase58                4pRXwS8kxg34Axt2x9nG7g                
  toBase32                0YX9Z0ZM06CJH9093BAW3ANY27            
  toHex                   0x1eea7e0fd00664a290246b5706aaf847    

Question

How does one configure the Doctrine Bridge UUID generator to generate V7 UUIDs?

You must be logged in to vote

Replies: 4 comments · 11 replies

Comment options

I don’t see how it could happen 🤔 could you provide a reproducer?

BTW UUID can be generated client-side, which avoids declaring your identifier nullable, which is better.

You must be logged in to vote
1 reply
@gnito-org
Comment options

It has something to do with this UuidFactory component:

 namespace Symfony\Component\Uid\Factory;

use Symfony\Component\Uid\Uuid;
use Symfony\Component\Uid\UuidV1;
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Uid\UuidV5;
use Symfony\Component\Uid\UuidV6;

class UuidFactory
{
    private string $defaultClass;
    private string $timeBasedClass;
    private string $nameBasedClass;
    private string $randomBasedClass;
    private ?Uuid $timeBasedNode;
    private ?Uuid $nameBasedNamespace;

    public function __construct(string|int $defaultClass = UuidV6::class, string|int $timeBasedClass = UuidV6::class, string|int $nameBasedClass = UuidV5::class, string|int $randomBasedClass = UuidV4::class, Uuid|string $timeBasedNode = null, Uuid|string $nameBasedNamespace = null)
    {
        if (null !== $timeBasedNode && !$timeBasedNode instanceof Uuid) {
            $timeBasedNode = Uuid::fromString($timeBasedNode);
        }

        if (null !== $nameBasedNamespace) {
            $nameBasedNamespace = $this->getNamespace($nameBasedNamespace);
        }

        $this->defaultClass = is_numeric($defaultClass) ? Uuid::class.'V'.$defaultClass : $defaultClass;
        $this->timeBasedClass = is_numeric($timeBasedClass) ? Uuid::class.'V'.$timeBasedClass : $timeBasedClass;
        $this->nameBasedClass = is_numeric($nameBasedClass) ? Uuid::class.'V'.$nameBasedClass : $nameBasedClass;
        $this->randomBasedClass = is_numeric($randomBasedClass) ? Uuid::class.'V'.$randomBasedClass : $randomBasedClass;
        $this->timeBasedNode = $timeBasedNode;
        $this->nameBasedNamespace = $nameBasedNamespace;
    }

    public function create(): Uuid
    {
        $class = $this->defaultClass;

        return new $class();
    }

The UuidGenerator class is instantiated with null as the $factory constructor parameter. Consequently it instantiates a vanilla instance of UuidFactory, which then defaults to UUID::v6.

namespace Symfony\Bridge\Doctrine\IdGenerator;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Symfony\Component\Uid\Factory\NameBasedUuidFactory;
use Symfony\Component\Uid\Factory\RandomBasedUuidFactory;
use Symfony\Component\Uid\Factory\TimeBasedUuidFactory;
use Symfony\Component\Uid\Factory\UuidFactory;
use Symfony\Component\Uid\Uuid;

final class UuidGenerator extends AbstractIdGenerator
{
    private readonly UuidFactory $protoFactory;
    private UuidFactory|NameBasedUuidFactory|RandomBasedUuidFactory|TimeBasedUuidFactory $factory;
    private ?string $entityGetter = null;

    public function __construct(UuidFactory $factory = null)
    {
        $this->protoFactory = $this->factory = $factory ?? new UuidFactory();
    }

When I dump the $factory parameter it is NULL:

    public function __construct(UuidFactory $factory = null)
    {
        dump($factory);
        $this->protoFactory = $this->factory = $factory ?? new UuidFactory();
    }
Comment options

The work-around is to not use the auto-generation in the entity:

    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME, unique: true)]
    private ?Uuid $id = null;

    public function __construct()
    {
        $this->id = Uuid::v7();
    }

It works fine with no problems.

You must be logged in to vote
6 replies
@gnito-org
Comment options

OK, but that has no bearing on the issue.

@mariusfaber98
Comment options

I think this workaround is no longer needed Symfony fixed it and now generates Uuids v7

@tfink
Comment options

Nothing is fixed for me, still generating v6 by default.

@wikando-mu
Comment options

I tried to created a own UuidV7Generator Class and used it as a CustomIdGenerator in my Doctrine Entity.

declare(strict_types=1);

namespace App\Entity\Doctrine;

use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Symfony\Component\Uid\Uuid;
use Symfony\Component\Uid\UuidV7;

class UuidV7Generator extends AbstractIdGenerator
{
    public function generateId(EntityManagerInterface $em, $entity): UuidV7
    {
        return Uuid::v7();
    }
}
    #[ORM\Id]
    #[ORM\Column(type: UuidType::NAME, unique: true)]
    #[ORM\GeneratedValue(strategy: 'CUSTOM')]
    #[ORM\CustomIdGenerator(class: UuidV7Generator::class)]
    public readonly Uuid $id;

With this Workaround a UuidV7 was saved in the Database.

@Tan5en5
Comment options

Hi everyone,

Same problem on our project, even with redeclaring manually uuid.factory and doctrine.uuid_generator services, problem is still there.

    uuid.factory:
        class: 'Symfony\Component\Uid\Factory\UuidFactory'
        arguments:
            $defaultClass: 7
            $timeBasedClass: 7
    doctrine.uuid_generator:
        class: 'Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator'
        arguments:
            $factory: '@uuid.factory'
Comment options

Seeing that this impacts many people I spent some time investigating what’s going on.

First, using the DoctrineBridge UuidGenerator is a bad idea since you’ll get a null ID until you persist the entity. Setting it in the constructor is simpler and get rid of this issue.
Plus, quoting the docs:

Using UUIDs as primary keys is usually not recommended for performance reasons: indexes are slower and take more space


If you don’t care about those issues, you need to register CustomIdGenerator’s class as a service. If you want it to use the default uuid.factory you don’t even need to configure it.

So, for the final answer:

services:
    Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator: ~
You must be logged in to vote
2 replies
@Tan5en5
Comment options

Many thanks for the explanations 🙂

@JiNexus
Comment options

@MatTheCat Thanks man! This is the correct answer for me!

Comment options

You can try to use the next one:

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

it's work for me

You must be logged in to vote
2 replies
@wikando-mu
Comment options

and you get a uuid v7 number? which symfony version?

@MarijnDoeve
Comment options

Can confirm with Symfony 7.3, this also seems to be the code that the maker bundle is generating when using the --with-uuid flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
🙏
Q&A
Labels
None yet
9 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.