Персонализирано хранилище на Symfony2, мързеливо зареждане и прокси обекти

Имам известен проблем с изтеглянето на свързани обекти от моята база данни с помощта на Doctrine2 в Symfony2. Имам персонализирано хранилище със следната функция:

public function getOrder($id) {
    $DQL = 'SELECT request, orderer
    FROM OrderRequestBundle:OrderRequest request
    JOIN request.orderer orderer
    WHERE request.id = :id';

    $query = $this->getEntityManager()->createQuery($DQL)
                ->setParameter('id', $id)
                ->setMaxResults(1);
    return $query->getResult();
}

... но по някаква причина, когато стартирам тази функция, получавам обратно прокси обект за обект OrderRequest, а не реално копие на OrderRequest, пропускам ли нещо? Изглежда, че Doctrine2 обича мързеливото зареждане и изглежда не мога да го вдигна от задника и да извлича обекти вместо мен.

АКТУАЛИЗАЦИЯ: Опитвам се просто да покажа информацията в шаблон на Twig с кода по-долу:

$order = $this->getDoctrine()
    ->getRepository('OrderRequestBundle:OrderRequest')
    ->getOrder($id);

return $this->render('OrderRequestBundle:Admin:view.html.twig', array('order' => $order));

Където Twig извиква информация за променливата „поръчка“ така:

{{ order.quantity }}

...но в крайна сметка получавам тази грешка:

Item "quantity" for "Array" does not exist in "OrderRequestBundle:Admin:view.html.twig" at line 5

person celestialorb    schedule 24.10.2011    source източник
comment
Има ли причина да не искате прокси екземпляр?   -  person Derek Stobbe    schedule 25.10.2011
comment
Опитвам се да взема информация за обекта OrderRequest за показване на страница (чрез шаблон на Twig), но продължавам да получавам грешката, че свойствата на обекта не съществуват. Ще актуализирам въпроса, за да отразя това.   -  person celestialorb    schedule 27.10.2011


Отговори (2)


АКТУАЛИЗАЦИЯ

Като се има предвид вашата редакция, проблемът изобщо не е в прокси обектите, а в начина, по който използвате вашия $query обект.

$query->getResult() ще върне масив от резултати. В пример като този, където ограничавате набора от резултати до максимум 1 ред, той ще върне масив с един запис, но все пак масив. Twig се задавя от това, когато се опитва да използва методи за достъп, естествено.

Това, което ще искате да направите, е да използвате $query->getSingleResult() вместо това. Обърнете внимание, че Doctrine ще хвърли изключение за неуникален резултат, ако заявката върне повече от един ред, така че трябва да сте сигурни, че ще я използвате с setMaxResults(1), както правите, ако заявката може евентуално да върне множество резултати.

КРАЙ НА АКТУАЛИЗАЦИЯТА

От документацията за референтни проксита:

Тук $item всъщност е екземпляр на прокси класа, който е генериран за класа Item, но вашият код не трябва да се интересува. Всъщност не трябва да го интересува. Прокси обектите трябва да са прозрачни за вашия код.

Подчертайте тяхното. Прокситата трябва да са прозрачни за вашия код и да съществуват, за да подобрят производителността, където е възможно; ако обаче имате належаща нужда да заредите нетърпеливо част от заявката, можете или да зададете режима на извличане в конфигурационния файл на вашия обект, или да разгледате този раздел от документите:

$query = $em->createQuery("SELECT u FROM MyProject\User u");
$query->setFetchMode("MyProject\User", "address", "EAGER");
$query->execute();
person Derek Stobbe    schedule 24.10.2011
comment
Благодаря ти! Предположих, че $query-›getSingleResult() ще даде същите резултати като $query-›setMaxResults(1), последвано от $query-›getResult(). Това свърши работа. :Д - person celestialorb; 27.10.2011

Doctrine2 винаги връща прокси обекти от заявки за хранилище. Те разширяват вашите класове на обекти и за всички намерения и цели са едно и също нещо.

Прокситата просто позволяват на вашите обекти да поддържат отложено зареждане на свързани обекти (наред с други неща).

Вижте http://www.doctrine-project.org/docs/orm/2.0/en/reference/working-with-objects.html?highlight=proxy#entity-object-graph-traversal

person Phil    schedule 24.10.2011