In my entity 'Item', there is an ArrayCollection property known as "products" (of Entity 'Product') that can be empty
I need all product info (empty or not) in one DQL call for the array of 'Item' entities
$query = $this->getEntityManager()->createQueryBuilder();
$query->select(['v', 'p'])->from($this->getEntityName(), 'v')
->join('v.products', 'p')
->orderBy('v.datePublished', 'DESC')
->setMaxResults($limit);
The problem here, is that the only records that get returned are ones that have at least one product in them. I need to return Items that have empty products as well.
Any thoughts?
Ok, so.. this is all that needed to happen:
$query = $this->getEntityManager()->createQueryBuilder();
$query->select(['v', 'p'])->from($this->getEntityName(), 'v')
->join('v.products', 'p')
->orderBy('v.datePublished', 'DESC')
->setMaxResults($limit);
becomes
$query = $this->getEntityManager()->createQueryBuilder();
$query->select(['v', 'p'])->from($this->getEntityName(), 'v')
->leftJoin('v.products', 'p')
->orderBy('v.datePublished', 'DESC')
->setMaxResults($limit);
I'm excited to get back to my life now.
Related
I have for example two tables: Parent and Children. They have relations many-to-many between each other. Everything is working well, but I don't know how to use where clause in query builder for this.
My code:
$parent = $em->getRepository('AppBundle:Parent')->find(1);
$qb = $em->createQueryBuilder();
$qb->select('c, p')
->from('AppBundle:Children', 'c')
->leftJoin('c.parents', 'p')
->where('p.id = :parent')
->setParameter('parent', $parent)
;
$childrens = $qb->getQuery()->getResult();
This always return me null.
I know - I can use $parent->getChildrens(), but I would like use createQueryBuilder for AppBundle:Children.
How should the where clause look?
I'm currently trying to build a query with the Doctrine2 QueryBuilder. However, I am stuck when trying to do the following:
I have an entity called 'Customer'. This entity stands in a ManyToMany-Relation to 'User'. 'User' again stands in a ManyToMany-Relation to PhoneNumber.
So it's pretty much:
Customer <- #ManyToMany -> User <- #ManyToMany -> PhoneNumber
Now I am trying to select a customer based on a PhoneNumber. So right now I have the following:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('c')
->from('AppBundle:Customer', 'c')
->join('AppBundle:User', 'u')
->join('AppBundle:PhoneNumber', 'u');
Problem now is that I don't know on how to build the where-section of the query. Reason is that there can be several users and several phone numbers bound to the customer. Do you have an idea on how to proceed?
If you have entities with mappedBy / InversedBy you can do
$qb = $this->getEntityManager()->createQueryBuilder();
$qb
->select('c')
->from('AppBundle:Customer', 'c')
->innerJoin('c.users', 'u')
->innerJoin('u.phoneNumbers', 'p')
->andWhere('p.number = :numberPhone')
->setParameter('numberPhone', $varPhoneNumber)
;
My solution:
Using innerJoin() and 'MEMBER OF' fixed the problem. This way I can connect every entity with any other entity. E.g:
$qb = $this->getEntitiyManager()->createQueryBuilder()
->select('c')
->from('AppBundle:Customer', 'c')
->innerJoin('AppBundle:User', 'u', 'WITH', 'c.id MEMBER OF c.users')
->innerJoin('AppBundle:PhoneNumber', 'ph', 'WITH', 'ph.id MEMBER OF u.phoneNumbers')
->orWhere($qb->expr()->orX(
$qb->expr()->eq('ph.number', ':number')
))
->setParameter('number', $somePhoneNumber);
An user has one role.
A role has zero or many users.
I would like to find roles without users.
I need to have this query without using IN or NOT IN
I tried with join:
$qb = $this->createQueryBuilder('role');
$qb
->leftJoin('role.users', 'users')
->where('users IS NULL')
without join
$qb = $this->createQueryBuilder('role');
$qb
->where('role.users IS NULL')
with id:
$qb = $this->createQueryBuilder('role');
$qb
->leftJoin('role.users', 'users')
->where('users.role != role')
Do you have other ideas? Do I have no other choices than to use IN / NOT IN queries?
Thanks in advance
You can find roles that don't have any users by using a count query
$qb = $this->createQueryBuilder('role');
$qb ->addSelect('COUNT(users.id) AS total_users')
->leftJoin('role.users', 'users')
->groupBy('role.id')
->having('total_users = 0')
->getQuery()->getResult();
I have two entities that share an abstract class creating class table inheritance. I can query for the entities by using the abstract class' repository and get all the entities that extend the abstract class as the result.
$qb = $this->createQueryBuilder('c')
->where('c.featured = true')
->orderBy('c.sticky', 'DESC')
->addOrderBy('c.weight', 'ASC')
->setFirstResult($offset)
->setMaxResults($limit);
// Returns 8 results, results in 34 queries
The sub classes contain ManyToMany relationships to other entities so if I query in this manner, those relationships result in additional queries since they are not being joined. How can you query for entities extending an abstract class and join their columns? I tried adding multiple from statements with left joins but the query returned fewer than the expected 8 results. That query builder looks something like this:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select(array(
'a', 'artist', 'country',
't', 'artwork', 'user'))
->from('AcmeArtworkBundle:Artwork', 'a')
->from('AcmeTourBundle:Tour', 't')
->leftJoin('a.artist', 'artist')
->leftJoin('a.country', 'country')
->leftJoin('t.artwork', 'artwork')
->leftJoin('t.user', 'user')
->where('a.featured = true')
->andWhere('t.featured = true')
->orderBy('a.sticky', 'DESC')
->addOrderBy('t.sticky', 'DESC')
->addOrderBy('a.weight', 'ASC')
->addOrderBy('t.weight', 'ASC')
->setFirstResult($offset)
->setMaxResults($limit);
// 5 results :-(
You can use a fetch join and Doctrine ORM's Paginator as described in the documentation:
$qb = $em->createQueryBuilder()
->select('c', 'd')
->from('MyInheritanceClass', 'c')
->join('c.d', 'd')
->where('c.featured = true')
->orderBy('c.sticky', 'DESC')
->addOrderBy('c.weight', 'ASC')
->setFirstResult($offset)
->setMaxResults($limit);
$paginator = new \Doctrine\ORM\Tools\Pagination($qb);
var_dump(count($paginator)); // 8 results, 2 queries
From the information provided by the link provided by #Ocramius, By default Doctrine loads entities using lazy loading. Associations are fetched only when they need to be. You can tell Doctrine to automatically fetch an association by setting the fetch mode to EAGER.
/**
* #var string $date
*
* #ORM\ManyToOne(targetEntity="Date", inversedBy="artwork", cascade={"persist"}, fetch="EAGER")
* #ORM\JoinColumn(name="date", referencedColumnName="id")
*/
private $date;
It's important to note that you can actually cause more queries to be run by doing this if you aren't careful.
I'm using Doctrine 2.
I want to get all Entities of an entity class except for the one with id = 0.
I could use QueryBuilder like this:
// $em is EntityManager
$em->createQueryBuilder()
->select('c')
->from('Category', 'c')
->where('c.id <> 0')
->getQuery()
->getResult();
But looking at this code, it feels like too much for such a simple task.
I'm curious to know if there is any other simpler way in Doctrine for doing this.
Nop, that's how you should do it. You could omit query builder and pass entire DQL query:
$em->createQuery("SELECT c FROM Category c WHERE c.id != 0")->getResult();
It's not the better practice to pass the ID number, you might pass the Category object like this :
public function findAllExcept($category) {
$qb = $this->createQueryBuilder('Category');
$qb->add('select', 'c')
->add('from', 'Category c')
->add('where', 'c != :category')
->setParameter('category', $category);
return $qb->getQuery()->getResult();
}
For comparisons and conditions I recommend use Doctrine as well. It will save your time in case of switch between databases, for instance MySQL to PostgreSQL:
$this->createQueryBuilder()
->select('c')
->from('Category', 'c')
->where($qb->expr()->neq('c.id', '?1'))
->setParameter('1', $category)
->getQuery()
->getResult()