Doctrine 2.5 Неожиданное поведение выборки ассоциации

У меня есть 3 объекта, связанные таким образом:

Не волнуйтесь, я установил ассоциации, используя аннотации, но я думал, что следующий микс будет легче / чище, чтобы разоблачить мою проблему

Post @ORM\ManyToOne(targetEntity="User", fetch="EAGER") - author User @ORM\OneToOne(targetEntity="Vip", mappedBy="user", fetch="EAGER") - vip Vip # Notice that the primary key of vip is a foreign key on User primary @ORM\id @ORM\OneToOne(targetEntity="User", inversedBy="peliqan", fetch="EAGER") @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false) - user 

Как вы можете видеть, все настроено на охоту.

Что мне нужно?

Я хотел бы получить наборы сообщений вместе с и то и другое пользователей & Vip информация ТОЛЬКО, используя один запрос . (см. править)

Прямо сейчас, для каждой записи в записи я получаю один дополнительный запрос:

 SELECT t0.valid AS valid_1, ... FROM vip t0 INNER JOIN user t10 ON t0.user_id = t10.id WHERE t0.user_id = ? 

когда:

  • Я выполняю это

     $results = $qb ->select('ps') ->leftJoin('ps.author','u')->addSelect('u') ->add('where', $qb->expr()->in('ps.id', $ids)) ->getQuery()->getResult(); 
  • и даже когда я пытаюсь использовать режим FETCH_EAGER, как это

     ->getQuery() ->setFetchMode('AppBundle\Entity\User', 'vip', ClassMetadata::FETCH_EAGER) ->getResult(); 

Заметка:
Мне удалось избавиться от дополнительного запроса путем enforcingQuery::HYDRATE_ARRAY при getResult() .
Запросы исчезли, что спасло треть первоначального времени.
Недостатком здесь является то, что при извлечении ассоциации в качестве массивов я больше не мог использовать Symfony\Component\Serializer\Annotation\Groups для фильтрации свойств объектов и вынужден вручную редактировать набор результатов, чтобы удалить / преобразовать некоторые значения.

РЕДАКТИРОВАТЬ

Уилт-ответ подходит для оригинального сообщения. Я не раскрыл свою проблему правильно. Я сказал, что хочу получить информацию Vip, потому что думал, что это хороший способ избавиться от дополнительного запроса, о котором я говорю выше. На самом деле мне не нужна информация Vip, но ->leftJoin('u.vip','v')->addSelect('v') заставляет доктрину выдавать дополнительный запрос, который собирает информацию Vip! Есть ли способ предотвратить доктрину от выполнения этого запроса?

В Doctrine2 есть два типа запросов присоединения:

1) Регулярные объединения
2) Собирать соединения

Проверьте раздел 14.2.2 документации . Объединяется для более подробной информации.

Поэтому, если вы хотите получить join vips, вы должны addSelect и leftJoin их в своем запросе следующим образом:

 $results = $qb ->select('ps') ->addSelect('u')->leftJoin('ps.author','u') ->addSelect('v')->leftJoin('u.vip','v') ->add('where', $qb->expr()->in('ps.id', $ids)) ->getQuery()->getResult(); 

ОБНОВИТЬ

Обновление после вашего комментария:

Я думал, что vip в результирующем наборе будет лучшим способом избавиться от дополнительного запроса

Вы не можете избавиться от дополнительного запроса, потому что вы не можете ленить загружать обратную сторону отношения «один к одному». См. Также этот пост для получения дополнительной информации:

Это ожидаемое поведение. Обратные стороны ассоциаций «один-к-одному» не могут быть ленивыми, технически. На обратной стороне нет внешнего ключа, поэтому невозможно решить, прокси-сервер или нет. Мы должны запросить связанный объект или присоединиться к нему. Обратите внимание, что это влияет только на обратные стороны однозначных ассоциаций, то есть на самом деле только обратную сторону двунаправленных взаимно однозначных ассоциаций.

  • Решением могло бы быть обратное отношение, так что пользователь становится владением отношения. В этом случае вы можете по крайней мере lazy-load Vip внутри вашего объекта User . Проблема с ленивой загрузкой переместилась бы на сторону Vip , а это значит, что вы больше не сможете lazy-load своего User в Vip .

  • В противном случае вы можете сделать запрос возвратом частичного объекта для предотвращения загрузки Vip , но в целом вы должны быть очень осторожны с этим подходом.