I have one problem in Symfony that I cannot solve.
I have one Entity class e.g. Category where I have e.g. $id, $name, $description, OneToMany User[] $members, OneToMany Book[] $books
Now... I need to get all categories (e.g. WHERE description IS NOT NULL) but in results, I don't want to have $books.
I need Category with id, name, description and [member1, member2...] but NO books.
I use something like:
$em->getRepository('AppBundle:Category')->findAll();
CodePudding user response:
You can use ->select('fieldA, fieldB')
to query specific fields.
Create a method in your repository to make your custom query:
public function findAllWithoutBooks()
{
return $this->createQueryBuilder('c')
->select('c.id, c.name, c.description')
->leftJoin('c.members', 'm')
->addSelect('m.id AS member_id, m.name AS member_name')
->andWhere('c.description IS NOT NULL')
->getQuery()
->getResult()
}
And use it like any other method:
$em->getRepository('AppBundle:Category')->findAllWithoutBooks();
CodePudding user response:
Doctrine by default uses Lazy fetching, meaning the books are not queried until after you call $category->getBooks()
. Using partial references is not needed as detailed below, unless the mapping fetch
declaration was changed to EAGER
for the association, provided you are not calling $category->getBooks();
Alternatively, a custom query using the partial
keyword can be used to explicitly select only the specified fields and hydrate partial Category
and associated User
objects.
Use of partial objects is tricky. Fields that are not retrieved from the database will not be updated by the
UnitOfWork
even if they get changed in your objects. You can only promote a partial object to a fully-loaded object by callingEntityManager#refresh()
or a DQL query with the refresh flag.
Example Query
$qb = $em->getRepository('AppBundle:Category')->createQueryBuilder('c');
$categories = $qb->select('partial c.{id, name, description}')
->leftJoin('c.members', 'm')
->addSelect('partial m.{id, name}')
->where($qb->expr()->isNotNull('c.description'))
->getQuery()
->getResult();
Result
array(
Category {
id,
name,
description,
members => array(
User {
id,
name
},
User {
id,
name
}
...
),
},
Category {
id,
name,
description,
members => array(
User {
id,
name
},
User {
id,
name
}
...
)
}
...
)