Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eager loading of related entity in Symfony 2

There are three entities: Customer, Messages, Attachments.

The relationship between these entities is straight forward: A customer can have many messages and a message can have many attachments. Both relations are "one-to-many".

I told doctrine to be lazy when loading the messages for the Customer entity. So $customer->getMessages() results in an additional SQL statement. That's fine.

But I also defined an "EAGER" loading for the attachments for the Message entity.

Now I would have expected that the messages I get by calling $customer->getMessages() are already loaded with all their attachments. But $message->getAttachments() still causes one SQL statement per message.

Is this behavior expected?

Just for reference, excepts from my classes:

Customer.php

class Customer
{
    /**
     * @ORM\OneToMany(targetEntity="Message", mappedBy="customer")
     * @ORM\OrderBy({"createdOn" = "DESC"})
     */
    private $messages;

Message.php

class Message
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="messages")
     * @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
     **/
    private $customer;
    /**
     * @ORM\OneToMany(targetEntity="Attachment", mappedBy="message", fetch="EAGER")
     **/
    private $attachments;

Attachment.php:

class Attachment
{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="Message", inversedBy="attachments")
     * @ORM\JoinColumn(name="message_id", referencedColumnName="id")
     **/
    private $message;
like image 282
Jens Avatar asked Feb 22 '15 12:02

Jens


1 Answers

It sounds like expected behavior to me. The doctrine documentation seems to imply that eager fetching is only one level deep.

According to the docs:

Whenever you query for an entity that has persistent associations and these associations are mapped as EAGER, they will automatically be loaded together with the entity being queried and is thus immediately available to your application.

http://doctrine-orm.readthedocs.org/en/latest/reference/working-with-objects.html#by-eager-loading

The entity being queried in your case is customer and customer has eager on messages so messages are populated. Messages, however are not the object being queried, so attachments do not get loaded.

like image 85
Derick F Avatar answered Oct 22 '22 19:10

Derick F