2014-09-15 25 views
5

Próbuję pobrać elementy z jednej klasy połączonej z inną klasą. Nie wszystkie podmioty faktycznie są połączone.Doctrine zwraca obiekt proxy podczas dołączania do tabeli z relacjami zerowymi

To trochę jak z następującym stwierdzeniem:

SELECT a, b FROM A a LEFT JOIN B b ON a.id = b.aid GROUP BY a.id; 

lub w kodzie:

$query_builder = $em->getRepository('repository_of_A')->createQueryBuilder('a'); 
$query_builder = $query_builder->leftJoin('a.b', b); 
$query_builder = $query_builder->groupBy('a.id'); 
$query = $query_builder->select('a, b')->getQuery(); 
$entities = $query->getResult(); 

Teraz problem jest, że gdy nie ma podmiot B do A, Doktryna zwraca obiekt proxy dla A. Ponieważ pracuję z odbiciami, potrzebuję rzeczywistego obiektu zamiast proxy.

Na załączonym obrazku obiekt z indeksem 26 nie ma odpowiadającego elementu B dla A (Sklep).

Shop Entity (A) is a Proxy

Czy ktoś wie dlaczego i jak mogę rozwiązać ten problem?

Uwaga: Wiem, że mogę po prostu przy użyciu odbicia użyć classname zamiast podmiotu, ale chciałbym również, aby zrozumieć problem tutaj, gdyż może to mieć wpływ na czas pracy ...

Edycja : Załączony zrzut ekranu

+0

Wydaje się dziwne. Czy ma na tym jakieś skojarzenia? W każdym przypadku, podczas używania Doctrine 2, musisz być w stanie obsługiwać proxy. – Cerad

+0

W rzeczywistości jest o wiele więcej skojarzeń, ale zapytanie prosi tylko o A i B. Cóż, używam 'ClassUtils :: getClass (...)' teraz, aby upewnić się, że refleksy będą nadal działać. Jednak nadal jestem zainteresowany rozwiązaniem tego problemu. – van

+0

Inne skojarzenia spowodują, że proxy zostaną stworzone w celu wspierania leniwego ładowania. Jedyne, co wiem o pracy, to dla ciebie konwersja danych lub stworzenie własnego hydratora Doctrine 2. Ale najlepiej jest po prostu poprzeć swój kod odbicia wsparciem proxy. – Cerad

Odpowiedz

0

Jeśli problem jest to, że pola nie są ładowane, a następnie przed użyciem sprawdzenie odbicia jeśli Doktryna ładowane jednostki i załadować go inaczej:

if (
    $object instanceof \Doctrine\Common\Persistence\Proxy 
    && !$object->__isInitialized() 
) { 
    $object->__load(); 
} 
// ... your code 

Ale jak widzę na zrzucie ekranu, błędnie zidentyfikowałeś ten problem. Jeśli najpierw wybierzesz a (tak jak w twoim przykładzie), na liście wyników nie będzie żadnych serwerów proxy.

Jak przypuszczam, w swoim przykładzie wszystkie podmioty sklepie są w jakimś związku (nie wybrany poprzez zapytania, ale na przykład z $country->getShops();) i Shop [70] proxy nie jest tylko dlatego, że gdzieś przed punktem Doktryna już załadowany go. Jeśli encja jest na mapie (według ID) - jest używana zamiast proxy, ponieważ jest już załadowana.

+0

Właściwie używam oświadczenia DQL, aby uzyskać dostęp do wszystkich sklepów z ich komentarzami podobnymi do opisanych powyżej. Zrzut ekranu pokazuje mój zestaw wyników podany przez to zapytanie. Dlatego nie rozumiem obiektu proxy. – van