HQL ha unito la query a desiderosi di recuperare un gran numero di relazioni

Il mio progetto ha recentemente scoperto che Hibernate può assumere più livelli di relazione e desiderosi di recuperarli in un unico HQL di join per produrre l’object riempito di cui abbiamo bisogno. Amiamo questa funzione, immaginando che potrebbe sovraperformare una pigra circostanza.

Il problema è che colpiamo una situazione in cui un singolo genitore ha una dozzina di relazioni dirette, alcune poche subrelationships fuori da questa, e alcune di esse hanno diverse dozzine di righe in poche istanze. Il risultato è un cross-product piuttosto grande che fa sì che la hql giri le sue ruote praticamente per sempre. Abbiamo triggersto la registrazione fino a 11 e abbiamo visto oltre 100000 iterazioni prima di abbandonare e uccidere.

Quindi, chiaramente, mentre questa tecnica è ottima per alcune situazioni, ha dei limiti come tutto nella vita. Ma qual è l’alternativa più performante in ibernazione per questo? Non vogliamo caricarli pigri, perché entreremo in una situazione N + 1 che sarà ancora peggio.

Preferirei che Hibernate pre-preleva tutte le righe e i dettagli, ma lo faccia una relazione alla volta, e quindi idrata l’object di dettaglio giusto al genitore giusto, ma non ho idea se faccia una cosa del genere.

Suggerimenti?

AGGIORNARE:

Quindi abbiamo ottenuto l’SQL generato da questa query, risulta che ho diagnosticato erroneamente il problema. Il prodotto incrociato NON è enorme. Abbiamo eseguito direttamente la stessa query nel nostro database e abbiamo ottenuto 500 righe restituite in poco più di un secondo.

Eppure abbiamo visto molto chiaramente nella registrazione di Hibernate facendo 100K iterazioni. E ‘ansible che Hibernate possa rimanere intrappolato nelle tue relazioni o qualcosa del genere?

O forse questo dovrebbe essere chiesto come una nuova domanda?

Il nostro team utilizza la strategia speciale per lavorare con le associazioni. Le collezioni sono pigre, anche le relazioni singole sono pigre, eccetto i riferimenti con una struttura semplice (ad esempio un riferimento ai paesi). E usiamo fluentemente-ibernato per caricare ciò di cui abbiamo bisogno in una situazione concreta. È semplicemente a causa di fluente-ibernato supporta proiezioni annidate. È ansible fare riferimento a questo test dell’unità per vedere come può essere parzialmente caricata la rete di oggetti complessi. Un frammento di codice dal test dell’unità

List roots = H. request(Root.class).proj(Root.ROOT_NAME) .innerJoin("stationarFrom.stationar", "stationar") .proj("stationar.name", "stationarFrom.stationar.name") .eq(Root.ROOT_NAME, rootName).transform(Root.class).list(); 

Guarda anche

Come trasformare un set di risultati flat usando Hibernate