2012-05-27 2 views
0

У меня есть объект под названием Категория со следующими полями:доктрина загружает все записи дважды

id: integer 
name: string 
slug: string 
children: OneToMany(targetEntity="Category", mappedBy="parent") 
parent: ManyToOne(targetEntity="Category", inversedBy="children") 

Как вы можете видеть, каждая категория может быть ребенок \ родителем другого.

Мне нужно отобразить все категории в массиве, так что я решил, что это будет лучше просто загрузить их все вместе:

$categoryRepository->findAll(); 

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

$category->getChildren(); 

Я предположил, что, поскольку я загрузил все категории в первую очередь, только один запрос будет выполнен, но профайлер показывает по-разному! Там является 1 запрос, где он получает все записи (вывода из профайлера):

SELECT t0.id AS id1, t0.name AS name2, t0.slug AS slug3, t0.parent_id AS parent_id4 
FROM acme_category t0 

А потом Существует еще один запрос для каждый запись:

SELECT t0.id AS id1, t0.name AS name2, t0.slug AS slug3, t0.parent_id AS parent_id4 
FROM omnt_work_category t0 WHERE t0.parent_id = 1 

SELECT t0.id AS id1, t0.name AS name2, t0.slug AS slug3, t0.parent_id AS parent_id4 
FROM omnt_work_category t0 WHERE t0.parent_id = 1 

etc.. 

Почему это ? Как я могу заставить его загружать все записи с первого места?

Спасибо!

ответ

0

Вы можете загрузить его автоматически, объявив fetch = "EAGER" в аннотации отношения.

Однако, глядя на вашу реализацию, похоже, что вы пытаетесь создать иерархию данных, поддерживая отношение child/parent. Возможно, вам лучше реализовать для этого вложенное множество решений. Там есть несколько библиотек для Doctrine 2, которые могут справиться с этим для вас.

Один я использовал и рекомендую >>https://github.com/blt04/doctrine2-nestedset

Сво, конечно, интересно, что доктрина пытается тянуть в ту же запись несколько раз вместо поиска кэша. Возможно, он немного по-другому обрабатывает кэширование реляционных элементов. Конечно, стоило бы расследовать.

+0

Вам необходимо настроить кэш результатов, чтобы он использовал кеш. По умолчанию он отключен для целей разработки (поскольку один и тот же запрос может возвращать другой результат). Doctrine только гарантирует отсутствие двух объектов с одним и тем же идентификатором одного и того же объекта в контексте вашего приложения. – meze

+0

@Lee, я добавил fetch = "EAGER" и получил 45 запросов =/Я попробую использовать указанную вами библиотеку и посмотреть, что произойдет. – tamir

+0

Вопрос об этой библиотеке: У меня есть несколько корневых узлов, как их получить ? fetchTree() извлекает только 1 дерево по его идентификатору. – tamir

Смежные вопросы