Как установить отложенную загрузку по умолчанию для Doctrine2? - PullRequest
0 голосов
/ 19 июля 2011

В настоящее время я в процессе переноса недавнего приложения Symfony 1.4 на Symfony2 и Doctrine2. Первое, что я заметил, когда преобразовал информацию отображения (мы используем файлы YAML), это то, что запросы для пользовательских объектов попали в бесконечный цикл. Я поиграл с ассоциациями и обнаружил, что у меня была цикличность. Я удалил его в целях отладки, удивляясь, почему он вообще перебирает все эти ассоциации. Я только что спросил всех пользователей.

Сегодня я снова столкнулся с той же проблемой с другим объектом, только он остановился после 930 запросов и не имел бесконечного цикла. Кажется, что Doctrine2, когда он заполняет объект, запрашивает все объекты для каждой ассоциации. Без проксирования, без ленивой загрузки.

Я включил fetch: LAZY для этой ассоциации и вуаля, автонаселение остановилось! Но теперь я хочу использовать это как поведение по умолчанию, так как модель имеет более 50 ассоциаций, и я не хочу добавлять эту строку ко всем из них.

Как мне активировать отложенную загрузку как настройку по умолчанию в Doctrine 2?

Ответы [ 2 ]

0 голосов
/ 20 июля 2011

После долгих потов и сводя модель к минимальному примеру, я выяснил, почему Doctrine выбирает все эти несколько строк.

Виновником был инструмент ORM, который я использую. Когда он импортировал существующую структуру базы данных, каждое отношение считалось отношением «один к одному». Изменение отношения «один ко многим» во всех 85 ассоциациях (как было бы правильно) должно сделать добился цели.

0 голосов
/ 19 июля 2011

Вот как работает ленивая загрузка. Когда вы пытаетесь получить связанный объект, Doctrine автоматически выдаст другой запрос. Теперь не рекомендуется использовать отложенную загрузку, особенно когда вы просто отображаете список объектов и связанных с ними объектов. Вот почему у вас 960 запросов! Тем не менее, Doctrine по умолчанию является ленивым, но вы можете быть агрессивны при извлечении связанных сущностей, присоединяя их к запросу, который приводит к одному запросу.

$blogs = $em->createQuery('SELECT b, p FROM Blog b JOIN b.posts p')->getResult();

Приведенный выше пример похож на SELECT b, p FROM Blog b, но при доступе к сообщениям Doctrine больше не будет выдавать другой запрос.

...