doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.94k stars 2.52k forks source link

Nested setFetchMode #11254

Open gharlan opened 8 months ago

gharlan commented 8 months ago

Feature Request

Q A
New Feature yes
RFC no
BC Break no

Summary

At the moment I'm using partial queries for fetching nested entities:

$qb = $this->createQueryBuilder('mail');
// ...
$mails = $qb->getQuery()->getResult();

$qb = $this->createQueryBuilder('mail');
$qb->select("PARTIAL mail.{id}, recipient, user");
$qb->andWhere("mail IN (:mails)")->setParameter('mails', $mails);
$qb->leftJoin('mail.recipients', 'recipient');
$qb->leftJoin('recipient.user', 'user');

Now I'm trying to convert this to setFetchMode (https://github.com/doctrine/orm/pull/8391) because partial queries are removed in v3. I've tried this:

$qb = $this->createQueryBuilder('mail');
// ...
$query = $qb->getQuery();

$query->setFetchMode(Mail::class, 'recipients', ClassMetadata::FETCH_EAGER); // this works great
$query->setFetchMode(MailRecipient::class, 'user', ClassMetadata::FETCH_EAGER); // this does not work

$mails = $query->getResult();

The second setFetchMode call does not have any effect. It would be great if setFetchMode would work for nested relations.

Or is there any other (good) replacement for my partial query?

beberlei commented 2 months ago

@gharlan I am assigning this to myself to take a look what we can do as soon as I have time, probably around the Doctrine Hackathon in October.

JanTvrdik commented 6 days ago

@gharlan We've recently published a library to work around the current limitations of setFetchMode and/or the need to write custom partial queries (which are now working again, yeah!) that should work for your use case.

This is how fetching nested entitiets from your example would look with the EntityPreloader.

$mails = $query->getResult();

$preloader = new EntityPreloader($entityManager);
$recipients = $preloader->preload($mails, 'recipients');
$preloader->preload($recipients, 'user');