DDC-3635: QueryBuilder - INSTANCE OF with parameter not working #4466

Open
opened 2026-01-22 14:42:14 +01:00 by admin · 8 comments
Owner

Originally created by @doctrinebot on GitHub (Mar 24, 2015).

Originally assigned to: @guilhermeblanco on GitHub.

Jira issue originally created by user Wilt:

I use single table class inheritance.
When I write my *INSTANCE OF* clause in my QueryBuilder like this:

    $result = $this->createQueryBuilder('o')
        ->leftJoin('o.child', 'c')
        ->where('c INSTANCE OF :entity_class')
        ->setParameter('entity_class', 'My\Entity\Class')
        ->getQuery()
        ->getResult();

It does not work correctly. The problem seems to lie in the fact that the parameter is bound to the SQL query. So if I change the entity_class to the discriminator column name it works correctly.

So if the discriminator value for *My\Entity\Class* would be discriminator then this does work:

    $result = $this->createQueryBuilder('o')
        ->leftJoin('o.child', 'c')
        ->where('c INSTANCE OF :entity_class')
        ->setParameter('entity_class', 'discriminator')
        ->getQuery()
        ->getResult();

So the step for getting the discriminator column from the class name is missing and instead the class name is bound to the MySql query directly.

Originally created by @doctrinebot on GitHub (Mar 24, 2015). Originally assigned to: @guilhermeblanco on GitHub. Jira issue originally created by user Wilt: I use single table class inheritance. When I write my **INSTANCE OF\* clause in my *QueryBuilder** like this: ``` $result = $this->createQueryBuilder('o') ->leftJoin('o.child', 'c') ->where('c INSTANCE OF :entity_class') ->setParameter('entity_class', 'My\Entity\Class') ->getQuery() ->getResult(); ``` It does not work correctly. The problem seems to lie in the fact that the parameter is bound to the SQL query. So if I change the **entity_class** to the discriminator column name it works correctly. So if the discriminator value for **My\Entity\Class\* would be *discriminator** then this does work: ``` $result = $this->createQueryBuilder('o') ->leftJoin('o.child', 'c') ->where('c INSTANCE OF :entity_class') ->setParameter('entity_class', 'discriminator') ->getQuery() ->getResult(); ``` So the step for getting the discriminator column from the class name is missing and instead the class name is bound to the MySql query directly.
admin added the Bug label 2026-01-22 14:42:14 +01:00
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Comment created by @guilhermeblanco:

INSTANCE OF expressions expect either their class names or their corresponding class metadata. This means the following examples are valid:

$qb->where('c INSTANCE OF My\Entity\Class');

// or

$qb
    ->where('c INSTANCE OF :param')
    ->setParameter('param', $em->getClassMetadata('My\Entity\Class'))
;

Assigning class name directly does not work.
Closing as invalid.

@doctrinebot commented on GitHub (Apr 8, 2015): Comment created by @guilhermeblanco: INSTANCE OF expressions expect either their class names or their corresponding class metadata. This means the following examples are valid: ``` $qb->where('c INSTANCE OF My\Entity\Class'); // or $qb ->where('c INSTANCE OF :param') ->setParameter('param', $em->getClassMetadata('My\Entity\Class')) ; ``` Assigning class name directly does not work. Closing as invalid.
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Comment created by @ocramius:

Re-opening. I think this is a documentation issue then, as http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#id2 says that the InstanceOfParameter accepts also an InputParameter

@doctrinebot commented on GitHub (Apr 8, 2015): Comment created by @ocramius: Re-opening. I think this is a documentation issue then, as http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html#id2 says that the `InstanceOfParameter` accepts also an `InputParameter`
Author
Owner

@doctrinebot commented on GitHub (Apr 8, 2015):

Comment created by @guilhermeblanco:

[~ocramius] And it does. However, the bound parameter must be a ClassMetadata.

@doctrinebot commented on GitHub (Apr 8, 2015): Comment created by @guilhermeblanco: [~ocramius] And it does. However, the bound parameter must be a ClassMetadata.
Author
Owner

@jycamier commented on GitHub (Feb 9, 2016):

It seams that there is a similar issue on the DoctrineORMAdapter object.

    $query = $this->createQueryBuilder('o')
        ->leftJoin('o.child', 'c')
        ->where('c INSTANCE OF :class')
        ->setParameter('class',  $em->getClassMetadata('My\Entity\Class'))
        ->getQuery();
    $adapter = new DoctrineORMAdapter($query);
    ...

This main query is okay : the mapping on the discriminator is done with the discriminator value. However, the subquery create to get the count isn't abble to do the job : the mapping is done with the string 'My\Entity\Class' and not the discriminator value.

@jycamier commented on GitHub (Feb 9, 2016): It seams that there is a similar issue on the DoctrineORMAdapter object. ``` php $query = $this->createQueryBuilder('o') ->leftJoin('o.child', 'c') ->where('c INSTANCE OF :class') ->setParameter('class', $em->getClassMetadata('My\Entity\Class')) ->getQuery(); $adapter = new DoctrineORMAdapter($query); ... ``` This main query is okay : the mapping on the discriminator is done with the discriminator value. However, the subquery create to get the count isn't abble to do the job : the mapping is done with the string 'My\Entity\Class' and not the discriminator value.
Author
Owner

@jarrettj commented on GitHub (Jul 6, 2021):

Does not work for me @jycamier. I had to put the class name in the parameter. Tried $em->getClassMetadata() no luck. Then played around with it and it works on the class name without the namespace, which is weird. Hey it works :).

@jarrettj commented on GitHub (Jul 6, 2021): Does not work for me @jycamier. I had to put the class name in the parameter. Tried $em->getClassMetadata() no luck. Then played around with it and it works on the class name without the namespace, which is weird. Hey it works :).
Author
Owner

@smilesrg commented on GitHub (Sep 27, 2021):

Issue from 24 Mar 2015, is it still relevant?

@guilhermeblanco maybe you know? :-)

@smilesrg commented on GitHub (Sep 27, 2021): Issue from 24 Mar 2015, is it still relevant? @guilhermeblanco maybe you know? :-)
Author
Owner

@Ocramius commented on GitHub (Sep 27, 2021):

@smilesrg would require a test - fairly sure it still doesn't work, since DQL was not refactored in that area.

@Ocramius commented on GitHub (Sep 27, 2021): @smilesrg would require a test - fairly sure it still doesn't work, since DQL was not refactored in that area.
Author
Owner

@jarrettj commented on GitHub (Jan 3, 2022):

Still does not work. :( Wasn't an issue as we simply had to do the instance check on the result set. Issue now is that the result set has become larger and there will be a performance issue. I had initially thought that the classname worked. But it did not.

Will do some more research and post findings.

@jarrettj commented on GitHub (Jan 3, 2022): Still does not work. :( Wasn't an issue as we simply had to do the instance check on the result set. Issue now is that the result set has become larger and there will be a performance issue. I had initially thought that the classname worked. But it did not. Will do some more research and post findings.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#4466