Desired loading of a related object in Symfony 2

There are three objects: Client, Messages, Attachments.

The relationship between these objects is straightforward: the client can have many messages, and the message can have many attachments. Both are one-to-many relationships.

I told the doctrine lazy when loading messages for the Customer object. Thus, $customer->getMessages() leads to an additional SQL query. It's fine.

But I also defined the "EAGER" load for attachments for the Message object.

Now I expected that the messages received when calling $customer->getMessages() were already loaded with all their attachments. But $message->getAttachments() still calls one SQL statement for each message.

Is this behavior expected?

For reference only, except for 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; 
+7
symfony doctrine2
source share
2 answers

This sounds like the expected behavior for me. The doctrine documentation seems to imply that impatient sampling is only one level.

According to the docs:

Whenever you request an entity that has permanent associations and these associations appear as EAGER, they will automatically be loaded with the requested entity and thus immediately available to your application.

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

The object requested in your case is a client and a client who craves messages, so messages are filled. Messages, however, are not the object of the request, so attachments are not loaded.

+6
source share

The correct code example might look like this:

NOTE. Extract message with lazy loading, i.e. receive messages with an additional request; as long as messages are retrieved from the database, the corresponding attachments referenced by each message will be downloaded automatically.

Customer

 class Customer { /** * @var integer * * @ORM\Column(name="id", type="integer") * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") */ private $id; /** * @ORM\OneToMany(targetEntity="Message", mappedBy="customer", fetch="LAZY") * @ORM\OrderBy({"createdOn" = "DESC"}) */ private $messages; 

Message

 class Message { /** * @var int * * @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="Attchment", mappedBy="message", fetch="EAGER") */ private $attachments; 

application

 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; 
+3
source share