21.10.2015 Views

1-33

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Symfony2 – Franz Jordán 2011<br />

Relationships and Proxy Classes<br />

This "lazy loading" is possible because, when necessary, Doctrine returns a "proxy" object in<br />

place of the true object. Look again at the above example:<br />

$product = $this->getDoctrine()<br />

->getRepository('AcmeStoreBundle:Product')<br />

->find($id);<br />

$category = $product->getCategory();<br />

// prints "Proxies\AcmeStoreBundleEntityCategoryProxy"<br />

echo get_class($category);<br />

This proxy object extends the true Category object, and looks and acts exactly like it. The<br />

difference is that, by using a proxy object, Doctrine can delay querying for the<br />

real Category data until you actually need that data (e.g. until you call$category->getName()).<br />

The proxy classes are generated by Doctrine and stored in the cache directory. And though you'll<br />

probably never even notice that your $category object is actually a proxy object, it's important<br />

to keep in mind.<br />

In the next section, when you retrieve the product and category data all at once (via a join),<br />

Doctrine will return the true Category object, since nothing needs to be lazily loaded.<br />

Joining to Related Records<br />

In the above examples, two queries were made - one for the original object (e.g. a Category)<br />

and one for the related object(s) (e.g. the Product objects).<br />

Remember that you can see all of the queries made during a request via the web debug toolbar.<br />

Of course, if you know up front that you'll need to access both objects, you can avoid the second<br />

query by issuing a join in the original query. Add the following method to<br />

the ProductRepositoryclass:<br />

// src/Acme/StoreBundle/Repository/ProductRepository.php<br />

public function findOneByIdJoinedToCategory($id)<br />

{<br />

$query = $this->getEntityManager()<br />

->createQuery('<br />

SELECT p, c FROM AcmeStoreBundle:Product p<br />

JOIN p.category c<br />

WHERE p.id = :id'<br />

)->setParameter('id', $id);<br />

}<br />

try {<br />

return $query->getSingleResult();<br />

} catch (\Doctrine\ORM\NoResultException $e) {<br />

}<br />

return null;<br />

Now, you can use this method in your controller to query for a Product object and its<br />

relatedCategory with just one query:<br />

98

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!