ramsey / uuid-doctrine

:snowflake::file_cabinet: Allow the use of a ramsey/uuid UUID as Doctrine field type.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrong query via relations

zys-gd opened this issue · comments

  • Expected outcome: 3b0b36c5ba224582bbb3dfacbf96fcd7
  • Actual outcome: [Object(Ramsey\Uuid\Uuid)]

The situation is that doctrine cant resolve relations.
I have an entities:

Entity_1:

type: entity
id:
    uuid:
        type: uuid_binary
        unique: true
        generator:
            strategy: CUSTOM
        customIdGenerator:
            class: '\Ramsey\Uuid\Doctrine\UuidGenerator'

`

Entity_2:

id:
    uuid:
        type: uuid_binary
        unique: true
        generator:
            strategy: CUSTOM
        customIdGenerator:
            class: '\Ramsey\Uuid\Doctrine\UuidGenerator'
manyToOne:
    owner:
        targetEntity: Entity_1
        cascade: {  }
        fetch: LAZY
        mappedBy: null
        inversedBy: null
        joinColumns:
            owner_id:
                referencedColumnName: uuid
        orphanRemoval: false
lifecycleCallbacks: {  }

And querybuilder:
$qb->where('s.owner = :owner') ->addOrderBy('s.created', 'DESC') ->setMaxResults(1) ->setParameter('owner', $owner);

In logs i see, that this query has not resolved to correct view, now its looks like
FROM entity_2 e0_ WHERE e0_.owner_id = 'Object(Ramsey\\Uuid\\Uuid)'
and not like i expect
FROM entity_2 e0_ WHERE e0_.owner_id ='3b0b36c5ba224582bbb3dfacbf96fcd7'

I found only 1 solution:

  1. public function getUuid() { return $this->uuid->getBytes(); }
  2. ... ->setParameter('owner', $owner->getUuid())

But this solution does not suit me for architectural requirements

I have a similar issue, the solution I found was ->setParameter('owner', $owner, 'uuid_binary') (or ->setParameter('owner', $owner, UuidBinaryType::NAME)) but it could be great if it could work without the type.

@orklah just because I was facing the same problem and couldn't find this solution... Where did you find this solution?

@nissen-chris I don't really remember, it was a year ago. Maybe something I deducted reading this:
#18
(which is another big issue I had with uuids, there is no good way to pass an array of ids in a request to perform an IN() with SQL)

@orklah Thank you for your quick reply!
No problem. I also found the other issue in this repository but was interested if I missed something bc I couldn't find anything helpful except your comment.

I have a similar issue, the solution I found was ->setParameter('owner', $owner, 'uuid_binary') (or ->setParameter('owner', $owner, UuidBinaryType::NAME)) but it could be great if it could work without the type.

I got this error with your solution:

request.CRITICAL: Uncaught PHP Exception PHPUnit\Framework\Error\Warning: "strlen() expects parameter 1 to be string, object given" at /usr/src/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php line 31 {"exception":"[object] (PHPUnit\Framework\Error\Warning(code: 2): strlen() expects parameter 1 to be string, object given at /usr/src/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php:31)"} {"token":"057f870d-48305172"}

I am using the string representation in the entity. The ID will be present as sting in the entity and then turned into the binary representation when it is persisted to the database.

Ah, ok, I have UuidInterface everywhere

I apologize for taking so long to look into this issue.

Is this still a problem, or did you find a work-around? What change could I make in ramsey/uuid-doctrine to help?

@ramsey well, the issue is that Doctrine don't seem to recognize an Uuid object as is when pushed as a param in a dql request (and so, try to inject [Object(Ramsey\Uuid\Uuid)] in the query).

An easy workaround is to give to setParameter a third param UuidBinaryType::NAME to help it recognize the type, but it's not obvious.

Looking at Doctrine's internals quickly, it doesn't look like there is a module to help infer a parameter type from the variable type (there is only a basic ParameterTypeInferer::inferType for native types). Not sure there's anything you can do, other than adding this to the doc