3
votes

I've run into an issue with the doctrine 2 paginator. I made a very basic example which will explain the situation:

$queryBuilder->select('entity');
$queryBuilder->join('SomeModule\Entity\SomeEntity', 's', 'WITH', '(s.objectClass = :class AND p.foreignKey = :foreignkey');
$paginator = new \Doctrine\ORM\Tools\Pagination\Paginator($queryBuilder);

causes the error 'Cannot count query which selects two FROM components, cannot make distinction' in: Doctrine\ORM\Tools\Pagination\WhereInWalker

It does that because there are two components, but in this case, no columns are selected from the 'SomeModule\Entity\SomeEntity':

if (count($rootComponents) > 1) {
    throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction");
}

In my case, it works when I comment the exception, because it will just use the first $rootComponent. Does anyone know a solution for this exotic join, without changing/extending the WhereInWalker class?

I used version 2.4.6 of the ORM, when I use the master branch: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Tools/Pagination/WhereInWalker.php The issue is resolved. But I'd rather not use the master branch in our environment.

1

1 Answers

2
votes

There is no solution for using exotic joins, without changing/extending the WhereInWalker class. The fix is now in Doctrine 2.5.0-alpha2 which is released now so you could upgrade to that if you'd like. 2.5 is scheduled to be released next month so you could wait until then if you'd like.

If you want to keep your existing Doctrine install as is changing the WhereInWalker and related classes is not terribly difficult. First you'll need to copy Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker Doctrine\ORM\Tools\Pagination\WhereInWalker and Doctrine\ORM\Tools\Pagination\CountWalker

From Doctrine master branch to your own code base and change the namespace accordingly. So you might use AcmeBundle\Components\Pagination\WhereInWalker or something similar.

You'll need to create your own Paginator which extends Doctrine\ORM\Tools\Pagination\Paginator and then copy past the functions count and getIterator from the parent class. Then update the functions to use your own Walkers you created above. So in count() You replace:

$this->appendTreeWalker($countQuery, 'Doctrine\ORM\Tools\Pagination\CountWalker');

with

$this->appendTreeWalker($countQuery, 'AcmeBundle\Components\Pagination\CountWalker');

Do the same for WhereInWalker and LimitSubqueryWalker in the getIterator method. Then everything will work fine. I just did something similar with the KnpPaginator to resolve this same issue. It does create a bit of maintenance headache so be sure to undo these things if you ever update to 2.5.