Reputation: 1314
I believe doctrine should always select all fields for an entity when it queries it. I'm using Kitpages' DataGrid bundle with the following code:
// create query builder
$repository = $this->getDoctrine()->getRepository('MyApplicationBundle:Application');
$queryBuilder = $repository->createQueryBuilder('a', 'u');
$queryBuilder->leftJoin('a.created_by', 'u'); // join user info
$gridConfig = new GridConfig();
$gridConfig
->setCountFieldName('a.id')
->addField(new Field('a.name', array('label'=>'col.name', 'sortable' => true, 'filterable'=>true)))
->addField(new Field('a.app_type', array('label'=>'col.type', 'sortable' => true, 'filterable'=>true)))
->addField(new Field('a.created_by', array(
'label'=>'col.user',
'sortable' => true,
'filterable'=>true,
'nullIfNotExists'=>true,
'formatValueCallback' => function($createdBy) {
if($createdBy instanceof \My\UserBundle\Entity\User)
return $createdBy->getName();
}
)))
;
Now I have some entities where created_by is null, and some where it is an id referencing a row in the fos_user table. I should be getting the name value for the entities that actually have a value in createdBy, but I'm getting empty columns in every row of the grid for the creator.
I'm my logs I can see the SQL that doctrine is fetching.
SELECT a0_.id AS id0, a0_.name AS name1, a0_.app_type AS app_type2, a0_.public AS public3, a0_.enabled AS enabled4, a0_.likegating AS likegating5, a0_.mobile_optimized AS mobile_optimized6, a0_.share_data AS share_data7, a0_.created_date AS created_date8, a0_.updated_date AS updated_date9 FROM application a0_ LEFT JOIN fos_user f1_ ON a0_.created_by_id = f1_.id LIMIT 15 OFFSET 15
It doesn't select a0_.created_by_id
at all. How do I get the select to include that field? I also tried changing the Field to 'u.name', but it didn't help.
Notice: In addition to changing my code to include the addSelect('u')
like the accepted answer mentions, I also changed my 'formatValueCallback'
to treat the variable as an array. Like so:
'formatValueCallback' => function($createdBy) {
if(isset($createdBy['name']))
return $createdBy['name'];
}
Upvotes: 1
Views: 6881
Reputation: 48893
So basically you are not getting u.name even though a relation exists?
Change:
$queryBuilder = $repository->createQueryBuilder('a', 'u');
The createQueryBuilder only takes one argument which will be an alias for your application object. The 'u' is ignored.
To:
$queryBuilder = $repository->createQueryBuilder('a');
$queryBuilder->addSelect('u');
And that will populate your user entity.
a0_.created_by_id does not show up in your select clause because it is used on the join statement to get the linked user object. created_by_id never actually get's stored in you application object. After making the above change, you can check the sql and will see a bunch of user attributes are now being selected.
===========================================================
And just for future reference, this is the code that your repository uses to make a query builder:
class Doctrine\ORM\EntityRepository
public function createQueryBuilder($alias)
{
return $this->_em->createQueryBuilder()
->select($alias)
->from($this->_entityName, $alias);
}
Upvotes: 3