По умолчанию Doctrine при загрузке объектов из таблиц с отношенимя OneToMany / ManyToOne использует несколько запросов (примеры здесь). В приведенных выше примерах были сделаны два запроса — один для исходного объекта (например, категории) и один для связанного объекта (объектов) (например, объектов Product).
В случае если требуедтся сразу получить всю информацию, то требуется использовать запрос с JOIN.
Если вы заранее знаете, что вам нужно получить доступ к обоим объектам, вы можете избежать второго запроса, выполнив объединение в исходном запросе. Добавьте следующий метод в класс ProductRepository:
// src/Repository/ProductRepository.php
public function findOneByIdJoinedToCategory($productId)
{
$entityManager = $this->getEntityManager();
$query = $entityManager->createQuery(
'SELECT p, c
FROM App\Entity\Product p
INNER JOIN p.category c
WHERE p.id = :id'
)->setParameter('id', $productId);
return $query->getOneOrNullResult();
}
Использование этого метода репозитория все равно вернет массив объектов Product. Но теперь, когда вы вызываете $product->getCategory() и используете эти данные, второй запрос не будет выполняться. Объект категории сразу будет доступен.
Теперь вы можете использовать этот метод в вашем контроллере для запроса объекта Product и связанной с ним category всего одним запросом:
public function show($id)
{
$product = $this->getDoctrine()
->getRepository(Product::class)
->findOneByIdJoinedToCategory($id);
$category = $product->getCategory();
// ...
}