Question: Doctrine query builder gives wrong result

Question

Doctrine query builder gives wrong result

Answers 2
Added at 2017-01-04 11:01
Tags
Question

I have two entities Person and Nursery and I have a ManyToMany relation between them with a JoinTable. I want to make this 2 sql queries :

1) Find all staff (= Person) linked to the nursery with an nursery_id

select p.* from person p inner join nursery_staff ns on p.id = ns.staff_id inner join nursery n on ns.nursery_id = n.id where n.id=1 and p.nursery_staff_role <> 'MANAGER';

2) Find the staff with staff_id and be sure that he's linked to the nursery with nursery_id

select p.* from person p inner join nursery_staff ns on p.id = ns.staff_id inner join nursery n on ns.nursery_id = n.id where n.id=2 and p.id=4 and p.nursery_staff_role <> 'MANAGER';

For that I have this 2 queries in the PersonRepository :

1 )

public function findAllStaffLinkedToANursery($nursery_id)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('p')
        ->from($this->_entityName, 'p')
        ->innerJoin('VSCrmBundle:Nursery', 'n')
        ->where('n.id = :id')
        ->andWhere('p.nurseryRole <> :profession')
        ->setParameters(array('id' => $nursery_id, 'profession' => 'MANAGER'));

    return $qb->getQuery()->getResult();
}

2)

public function findOneByNurseryAndStaffId($nursery_id, $staff_id)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('p')
        ->from($this->_entityName, 'p')
        ->innerJoin('VSCrmBundle:Nursery', 'n')
        ->where('p.id = :pid')
        ->andWhere('n.id = :nid')
        ->andWhere('p.nurseryRole <> :staffRole')
        ->setParameters(array(
            'pid' => $staff_id,
            'nid' => $nursery_id,
            'staffRole' => 'MANAGER'
        ));

    return $qb->getQuery()->getOneOrNullResult();
}

But in both cases that queries doesn't care of the nursery_id and that gives me the staff undepended of the nursery_id. For example, the Person with id=4 is not linked with the nursery with id=2 but this query shows me this person.

EDIT : I have the same result with dql query :

 php bin/console doctrine:query:dql "select p.email from VSCrmBundle:Person p inner join VSCrmBundle:Nursery n where n.id=2 and p.nurseryRole <> 'MANAGER'"
Answers
nr: #1 dodano: 2017-01-04 14:01

Maybe it's the way how you join the Nursery entity. Try to join it from the Person entity attribute like this:

public function findAllStaffLinkedToANursery($nursery_id)
{
    $qb = $this->_em->createQueryBuilder();
    $qb->select('p')
        ->from($this->_entityName, 'p')
        ->innerJoin('p.nursery', 'n')
        ->where('n.id = :id')
        ->andWhere('p.nurseryRole <> :profession')
        ->setParameters(array('id' => $nursery_id, 'profession' => 'MANAGER'));

    return $qb->getQuery()->getResult();
}

This of course only works, if Person has the attribute nursery and it's mapped with Doctrine ORM. If the repository extends Doctrine\ORM\EntityRepository you can also simplify it:

public function findAllStaffLinkedToANursery($nursery_id)
{
    $qb = $this->createQueryBuilder('p');
    $qb->innerJoin('p.nursery', 'n')
        ->where('n.id = :id')
        ->andWhere('p.nurseryRole <> :profession')
        ->setParameters(array('id' => $nursery_id, 'profession' => 'MANAGER'));

    return $qb->getQuery()->getResult();
}
nr: #2 dodano: 2017-01-04 14:01

Ok thanks to Sepultura my code works ! I dit this :

public function findAllStaffLinkedToANursery($nursery_id)
{
    $qb = $this->createQueryBuilder('p');
    $qb->innerJoin('p.nurseries', 'n')
        ->where('n.id = :id')
        ->andWhere('p.nurseryRole <> :profession')
        ->setParameters(array('id' => $nursery_id, 'profession' => 'MANAGER'));

    return $qb->getQuery()->getResult();
}
Source Show
◀ Wstecz