K
K
KerryDarko2016-02-08 01:19:43
symfony
KerryDarko, 2016-02-08 01:19:43

Doctrine: one-to-one relationship in annotations: why does lazy loading work immediately?

I have two entities with a one-to-one relationship described in annotations

/**
     * @ORM\OneToOne(targetEntity="Subdomain", mappedBy="company")
     */
    protected $subdomain;

    ...

    /**
     * @ORM\OneToOne(targetEntity="Company", inversedBy="subdomain")
     * @ORM\JoinColumn(name="target_id", referencedColumnName="id")
     */
    private $company;

There is an example in the documentation :
$product = $this->getDoctrine()
        ->getRepository('AppBundle:Product')
        ->find($id);

    $categoryName = $product->getCategory()->getName();

And it is said:

When you call $product->getCategory()->getName(), Doctrine silently makes a second query to find the Category that's related to this Product.
What's important is the fact that you have easy access to the product's related category, but the category data isn't actually retrieved until you ask for the category (ie it's "lazily loaded").

And if you write a query by hand:
$repository = $this->get('doctrine')->getRepository('TestBundle:Company');

    $qb = $repository->createQueryBuilder('c');
    $qb
            ->where('(c.id = :id)')
            ->setParameter('id', 1);
    $query = $qb->getQuery();

    $val = $query->getOneOrNullResult();

Then two requests go to the database at once: a selection of a company and a selection of a subdomain.
Why is that?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
vendetto, 2016-02-11
@KerryDarko

This is a long known behavior, the answer is at the link .
Solution: Leave the relationship only on the owner side - it's the entity that has the relationship. In your case Subdomain. Or change the owner.

D
Dmitry Vapelnik, 2016-02-11
@dvapelnik

Hi guys!
the question is not really clear. at least for me personally
, when selecting objects through find, lazy loading is used: for AppBundle:Productobjects, all its fields are selected, and for all relations, proxy objects are formed, through which, through additional queries to the database, you can get the relationship objects themselves.
There is a nuance when using DQL:
maybe you missed something? in one case you are referring to AppBundle:Product, in the second to TestBundle:Companyand you are talking about subdomain fetching
lazy loading always happens unless you use join, or explicitly specify to fetch relation entities likeEAGER

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question