Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symfony/Doctrine fail to find an entity based off of its binary UUID #264

Open
BenoitDuffez opened this issue May 10, 2024 · 3 comments
Open
Labels

Comments

@BenoitDuffez
Copy link

I have created a new Symfony app with version 7.0.7 and doctrine/orm ^3.1. I followed the instructions to use binary UUIDs and then created a CRUD for my entities. Entity A is standalone and works well. Entity B has a ManyToOne relation to A and while the form displays fine, I can't validate it and thus create a new B.

I was able to pin the issue here, in vendor/symfony/doctrine-bridge/Form/ChoiceList/ORMQueryBuilderLoader, line 70:

            // Filter out non-integer values (e.g. ""). If we don't, some
            // databases such as PostgreSQL fail.
            $values = array_values(array_filter($values, fn ($v) => (string) $v === (string) (int) $v || ctype_digit($v)));
        } elseif (\in_array($type, ['ulid', 'uuid', 'guid'])) { // <-----
            $parameterType = ArrayParameterType::STRING;

now if I modify this to:

            // Filter out non-integer values (e.g. ""). If we don't, some
            // databases such as PostgreSQL fail.
            $values = array_values(array_filter($values, fn ($v) => (string) $v === (string) (int) $v || ctype_digit($v)));
        } elseif (\in_array($type, ['ulid', 'uuid', 'guid', 'uuid_binary'])) {
            $parameterType = ArrayParameterType::STRING;

then it works like a charm.

I feel like I have missed something in the setup of this lib but I can't pinpoint what/where.

config/packages/doctrine.yaml

doctrine:
    dbal:
        url: '%env(resolve:DATABASE_URL)%'
        profiling_collect_backtrace: '%kernel.debug%'
        use_savepoints: true
        types:
            uuid_binary:  Ramsey\Uuid\Doctrine\UuidBinaryType

I also tried this in my Kernel but that does not work either:

public function boot(): void {
     parent::boot();
    \Doctrine\DBAL\Types\Type::addType('uuid_binary', 'Ramsey\Uuid\Doctrine\UuidBinaryType');
    $entityManager = $this->getContainer()->get('doctrine.orm.default_entity_manager');
    $entityManager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('uuid_binary', 'binary');
}
@subdee
Copy link

subdee commented May 14, 2024

.

@BenoitDuffez
Copy link
Author

Your comment is valid for querying the database. Indeed we need to set a parameter to the bytes of the UUID. One note about your code though, I think it would be easier with

->setParameter(':column', $client->getId()->getBytes())

indeed, the getId returns a UUID that you can extract the bytes from.

However, my ticket was about forms. If you declare relationships between two entities, they are linked with their UUID and it works fine in the database. The problem is that when saving the form, the form data type is uuid_binary and Symfony has a static check that does not include this (but does include uuid).

Changing Symfony code is wrong, perhaps an upstream patch would be accepted but it also feels wrong to me. I don't know if there are events or configuration items that can be leveraged by this library so that Symfony knows how to handle uuid_binary.

PS: by "Symfony" I mean symfony/doctrine-bridge

@subdee
Copy link

subdee commented May 20, 2024

@BenoitDuffez You are right, they are not related, I will make a separate issue for my problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants