5
votes

I'm running into a problem with the Doctrine Paginator.

In my repository I have a function to retrieve a specific dataset. I use the querybuilder for this:

{myEntityRepository}->createQueryBuilder($alias)

In order to select only specific fields I use the following:

if (count($selectFields) > 0) {
    $qb->resetDQLPart('select');
    foreach ($selectFields as $selectField) {
        $qb->addSelect($alias . '.' . $selectField);
    }
}

This works fine when I retrieve the whole set like this:

$query = $qb->getQuery();
$data = $query->getResult(AbstractQuery::HYDRATE_ARRAY);

But it fails when I use the paginator:

$paginator = new Paginator($qb, $fetchJoinCollection = false);
$total = $paginator->count(),
$data = $paginator->getQuery()->getResult(AbstractQuery::HYDRATE_ARRAY)

I get the error:

Not all identifier properties can be found in the ResultSetMapping: relationID
\vendor\doctrine\orm\lib\Doctrine\ORM\Query\Exec\SingleSelectExecutor.php(38)

Question: Why does the paginator fail when I select only specific fields?
Am I overlooking something? Or am I doing it wrong all together?

2
Man, I feel so like this... xkcd.com/979 - yivi

2 Answers

0
votes

i am using this solution.

add use statements

use Zend\Paginator\Paginator;
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as DoctrineAdapter;
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;

in your action

$viewModel = new ViewModel();

$entityManager = $this->getServiceLocator()
    ->get('Doctrine\ORM\EntityManager');

$queryBuilder = $entityManager
    ->createQueryBuilder();
$queryBuilder->add('select', new Expr\Select(array('t.id', 't.name')));
$queryBuilder->add('from', 'Application\Entity\Table t');

$adapter = new DoctrineAdapter(
    new ORMPaginator(
        $queryBuilder
    )
);
$paginator = new Paginator($adapter);
$paginator->setDefaultItemCountPerPage(20);

$page = (int)$this->params()->fromQuery('page');
if($page) $paginator->setCurrentPageNumber($page);

$viewModel->results = $paginator;

return $viewModel;
-1
votes

Doctrine is trying to hydrate a relationship outlined by your YAML file, using a field that doesn't exist because you've excluded it from your SELECT statement. Take a look at your mapping file to figure out what you need to add back in.

I would think that it's only complaining with the Paginator because the field is not being accessed (and therefore not being lazy-loaded) when you don't use the Paginator.

As an aside (and with zero understanding of your stack, so YMMV) I would avoid making a habit of SELECTing reduced result sets, as you'll find yourself running into odd issues like this all the time. If you do need extra performance, you'd be better off putting a good old caching layer in place...