Symfony и Doctrine: ленивая загрузка не работает

Использование Symfony 2.8.

я имею сообщество а также Пункт меню лица, где сообщество имеет набор Пункты меню.

Community.php имеет следующий код:

...
/**
* @ORM\OneToMany(targetEntity="MenuItem", mappedBy="community", fetch="LAZY")
* @ORM\OrderBy({"sequence" = "ASC"})
*/
private $menuItems;
...

MenuItem.php имеет следующий код:

...
/**
* @var Community
*
* @ORM\ManyToOne(targetEntity="Community", inversedBy="menuItems")
*/
private $community;
...

Дело в том, когда я использую:

$menuItems = $community->getMenuItems();

$menuItems переменная будет пустой коллекцией.

Проблема может быть решена путем установки fetch="EAGER" вместо fetch="LAZY"потому что таким образом $menuItems атрибут категория Сущность загружается немедленно.

Ленивый против EAGER (источник):

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

Всякий раз, когда вы запрашиваете объект, который имеет постоянные ассоциации, и эти ассоциации отображаются как EAGER, они автоматически загружаются вместе с запрашиваемым объектом и, таким образом, сразу же становятся доступными для вашего приложения.

Дело в том, что в то время как загрузка EAGER работает, как ожидалось, загрузка LAZY кажется не работает вообще. Есть идеи о том, почему?

1

Решение

Когда вы делаете $community->getMenuItems(); :

  • В режиме EAGER: данные уже получены, поэтому массив возвращается.
  • В режиме LAZY: запрос к базе данных выполняется при выполнении вызова. За кулисами это работает, генерируя «прокси» перед вашими сущностями, которые будут называть вас доктриной.

Осторожно с ленивой загрузкой:

Обход графа объектов для ленивых загрузок легко вызовет множество SQL-запросов и будет плохо работать, если их интенсивно использовать.

Лучше получать данные напрямую, используя DQL-выборку. Смотри например http://blog.bemycto.com/good-practices/2015-05-31/understanding-doctrine-orm-lazy-load-fetch-join/

0

Другие решения

Лично я не фанат ленивой / энергичной загрузки, так как многие запросы будут запущены, когда они могут быть выполнены в одном запросе с объединениями.

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

0

Это, кажется, работает, чтобы загрузить ленивые отношения.

$logs = $entity->getLogs(); // lazy relationship
$this->getDoctrine()->getManager()->initializeObject($logs);

$ logs теперь будет заполняться.

Документы для initializeObject:

Вспомогательный метод для инициализации отложенной загрузки прокси или постоянного
коллекция.

0
По вопросам рекламы [email protected]