user1185430
user1185430

Reputation: 35

Doctrine and ManyToOne entity

I have two entities, country and Province, and I have set up a many-to-one relation in the Province entity:

Entity/Province

/**
 * @var \AppBundle\Entity\Country
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country")
 * @ORM\JoinColumn(name="ubicacionpaisid", referencedColumnName="id")
 *
 */
private $ubicacionpaisid;

Here I get all results using the Province entity:

 $cb = $this->getDoctrine()
        ->getEntityManager()
        ->getRepository(Province::class)
        ->createQueryBuilder('a');

However, if I run:

 var_dump($cb->getQuery()->getDQL());

it returns:

string(41) "SELECT a FROM AppBundle\Entity\Province a"

What I expected to see was a query that joins the Country entity, into the Province entity in the SQL.

What am I missing ?

Upvotes: 1

Views: 481

Answers (3)

Enumus
Enumus

Reputation: 66

As DarkMukke said...

Did you try to fetch the data?

Adding in your relation fetch="EAGER"

/**
 * @var \AppBundle\Entity\Country
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", fetch="EAGER")
 * @ORM\JoinColumn(name="ubicacionpaisid", referencedColumnName="id")
 *
 */
private $ubicacionpaisid;

This should fetch and load the associated entity as well.

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#manytoone

Upvotes: 0

Jason Roman
Jason Roman

Reputation: 8276

I realize 2 people gave answers that just say to use EAGER loading of the association. But I can't recommend that. This makes so many assumptions about your project and how you'd always want to join that association no matter what, and can even cause issues with forms and creating unexpected behavior.

Plus, the user already is showing that they're using a custom QueryBuilder call to grab the data, so why not explicitly use the join?

For example:

$cb = $this->getDoctrine()->getEntityManager()->getRepository(Province::class)
    ->createQueryBuilder('p')
    ->select('p, c')
    ->join('p.ubicacionpaisid', 'c')
    ->getQuery()
    ->getResult()
;

or better yet, from with a ProvinceRepository:

return $this->createQueryBuilder('p')
    ->select('p, c')
    ->join('p.ubicacionpaisid', 'c')
    ->getQuery()
    ->getResult()
;

Upvotes: 1

DarkMukke
DarkMukke

Reputation: 2489

This might be because Doctrine has 2 types of joins. A normal join and a fetch join. In the fetch join, Doctrine will preform 2 different queries and then just hydrate the result of the second back into the result/data of the first.

It's sometimes also referred to as a lazy join. Lazy joins are the default behavior.
You can change this behavior by altering your relation with fetch="EAGER"

/**
 * @var \AppBundle\Entity\Country
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Country", fetch="EAGER")
 * @ORM\JoinColumn(name="ubicacionpaisid", referencedColumnName="id")
 *
 */

Upvotes: 2

Related Questions