5

I'm using Symfony2 with Doctrine2 (latest versions) and have this relation defined:

/**
 * @ORM\OneToMany(targetEntity="Field", mappedBy="event", fetch="EAGER")
 * @ORM\OrderBy({"name" = "ASC"})
 */
protected $fields;

The other side of the relation is defined as:

/**
 * @ORM\ManyToOne(targetEntity="Event", inversedBy="fields", fetch="EAGER")
 * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
 */
protected $event;

When doing a "fetchOnyById", Doctrine runs 2 queries. 1 to fetch the object itself and 1 for the related fields. I would expect this to be a join, but it isn't.

When done in the controller, I pass my object to twig. There I retrieve the fields again as a property of the object. This causes another query to be run to retrieve the fields again.

Clearly I'm doing something wrong, as I would expect only 1 query to be run and 3 are actually run.

DoppyNL
  • 1,415
  • 1
  • 14
  • 24
  • Basically the idea is not to think like you're working with SQL but to think like you're working with objects with real associations and letting Doctrine load and create those situations. If you come to a situation though where you need a joined query, it can be easily created with DQL – Moylin Aug 10 '13 at 07:07

1 Answers1

3

I believe the reason this is occurring is because you're fetching entities, not a specific query. The idea of Doctrine is that you're fetching objects, not interacting with a database but an object resource as if they're all associated/referenced like stored entities. If you need a query like you're describing you would be better off using DQL but at that point you're not fetching entities created, you're getting a custom result.

I hope this made sense.

Basically the default association you're using is fetching associated objects not a joined query.

Moylin
  • 737
  • 1
  • 9
  • 20
  • 3
    So basically this is how eager loading in Doctrine2 works. A separate query for the related objects is run just after the first for the object. Then the use of eager loading is a bit less than I thought and generally you are best of using lazy loading. In special cases a join might be useful, but that would be an extra method in the repository that runs a custom query. Basically: my expectations of the behavior were wrong. tnx! – DoppyNL Aug 10 '13 at 07:36
  • well, maybe. Be careful as to what you do as sometimes you might end up pulling 100+ queries on something simple because you only maybe requested X entity, but then using that entity you start making calls to associations that each pull when you query them. I try to use a mix of DQL and direct entities depending on which is better suited. – Moylin Aug 12 '13 at 18:11
  • I noticed something like that happening on some pages. Querycount grew to nearly 100. The database won't be that big however, and currently it is faster than running 1 big join. Is it possible to run a custom DQL query when fetching a relation from the database? That way I can load all related objects in one go. – DoppyNL Aug 13 '13 at 08:23
  • I think you'll have to use at least a few if you want them as associated objects. But you can keep the count low still. such as query for your primary entity. then have a custom repository function to query all associated entities for association A. Aka query for user A, then have another function to query for all of his blog posts to associate them to him. DQL is the in between you all you need is specific information you can fetch as one query that may not need to be relational entities such as if you're building out a display on a specific page. – Moylin Aug 13 '13 at 12:39
  • But if you were trying to setup that content into a form, you'd want to use entities directly as otherwise it'd get hairy. – Moylin Aug 13 '13 at 12:40