2014-09-15 19 views
5

Sto tentando di recuperare entità da una classe unita a un'altra classe. Non tutte le entità hanno effettivamente entità unite.Doctrine restituisce oggetto proxy quando unisce una tabella con relazioni nullable

E 'un po' come la seguente dichiarazione:

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

o nel codice:

$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(); 

Ora il problema è che ogni volta che c'è nessuna entità B per A, Doctrine restituisce un oggetto proxy per A. Poiché lavoro con i riflessi, ho bisogno dell'oggetto reale anziché del proxy.

Nello screenshot allegato l'oggetto con indice 26 non ha un'entità B corrispondente per A (Shop).

Shop Entity (A) is a Proxy

Qualcuno sa perché e come posso risolvere questo problema?

Nota: So che ho potuto solo usare il nome di classe al posto del soggetto quando si utilizzano le riflessioni, ma vorrei anche capire il problema qui come può influenzare il tempo di esecuzione ...

Edit : Attaccati una schermata

+0

Sembra strano. Ci sono altre associazioni su di esso? In ogni caso, quando si utilizza Doctrine 2 è necessario essere in grado di gestire i proxy. – Cerad

+0

In realtà ci sono molte più associazioni, ma la query richiede solo A e B. Bene, io uso 'ClassUtils :: getClass (...)' ora per assicurarmi che le riflessioni funzionino ancora. Tuttavia, sono ancora interessato a risolvere questo problema. – van

+0

Le altre associazioni causeranno la creazione di proxy per supportare il caricamento lento. L'unico lavoro intorno a quello che so sarebbe per te fare una sorta di conversione dei dati o creare il tuo idratante Doctrine 2. Ma la cosa migliore da fare è semplicemente avere i proxy di supporto del codice di riflessione. – Cerad

risposta

0

Se il problema è che i campi non vengono caricati, quindi prima di utilizzare controllo riflessione se dottrina caricato dell'entità e caricarlo altrimenti:

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

Ma come vedo dal tuo screenshot, hai identificato erroneamente il problema. Se si seleziona a per primo (come nel proprio esempio), quindi non ci saranno proxy nella lista dei risultati.

Come direi, nel tuo esempio tutte le entità negozio sono in qualche associazione (non selezionato tramite query, ma per esempio da $country->getShops();) e Shop [70] non è un proxy solo perché da qualche parte prima che la Dottrina punto è già caricata esso. Se l'entità è nella mappa (per ID), viene utilizzata al posto del proxy poiché è già stata caricata.

+0

In realtà io uso una dichiarazione DQL per far aderire tutti i negozi ai loro commenti simili a quelli descritti sopra. Lo screenshot mostra il mio set di risultati dato da quella query. Ecco perché non capisco l'oggetto proxy. – van