I would like to paginate a complex request with at least 2 left joins, but the pagination bundle I\'m using (KnpPaginationBundle) can\'t tell Doctrine how to count the resul
If you aren't working with regular mapped entities in the way supplied in the answers above, joins will create additional components in the result set. This means the set cannot be counted since its not a scalar result.
So the key is keeping your result sets to one component which will allow a scalar result to be produced and counted.
You can convert a regular field to an entity mapping at run time. This allows you to write queries with only one component returned even if you're joining other entities at random. The 'other entities' become a child of the main entity as opposed to an additional root entity or extra component of the result.
The example below shows a one-to-one mapping. I haven't tried more complex mappings but my success with this suggests it should be possible. The Registration entity has a field called user that contains a user Id, but its not a mapped entity just a plain field.
(This has been modified from a working example but not tested as is - so treat as pseudo-code)
$queryBuilder // The query builder already has the other entities added.
->innerJoin('r.user', 'user')
;
$mapping['fieldName'] = 'user';
$mapping['targetEntity'] = '\YourBundle\ORM\Model\User';
$mapping['sourceEntity'] = '\YourBundle\ORM\Model\Registration';
$mapping['sourceToTargetKeyColumns'] = array('user' => 'id');
$mapping['targetToSourceKeyColumns'] = array('id' => 'user');
$mapping['fetch'] = 2;
$mapping['joinColumns'] = array(
array(
'name' => 'user',
'unique' => false,
'nullable' => false,
'onDelete' => null,
'columnDefinition' => null,
'referencedColumnName' => 'id',
)
);
$mapping['mappedBy'] = 'user';
$mapping['inversedBy'] = null; // User doesn't have to link to registrations
$mapping['orphanRemoval'] = false;
$mapping['isOwningSide'] = true;
$mapping['type'] = ClassMetadataInfo::MANY_TO_ONE;
$vm = $this->em->getClassMetadata('YourBundle:Registration');
$vm->associationMappings["user"] = $mapping;
Note: I was using PagerFanta not KNP - but the problem lies with Doctrine so I expect this will work anywhere.