hibernate many-to-one di query HQL, quando inner join prendere proprietà non associato
-
11-09-2019 - |
Domanda
Ho un'associazione molti-a-uno impostato come questo, nel hbm.xml:
<many-to-one name="gigVenue"
class="blah.blah.xxx" fetch="select"
lazy="no-proxy" not-null="true" >
<column name="N_VENUE_ID" precision="18" scale="0" not-null="true" />
</many-to-one>
E io sto usando la strumentazione per fare vera lazy loading.
MA quando si esegue una query HQL con un inner join fetch all'altra tabella, la proprietà che dovrebbe contenere l'oggetto che è il valore dell'altra tavola, è lasciato come nullo. Anche se posso vedere oggetti di valore dell'altro tavolo stata creata da Hibernate.
Qualcuno ha qualche comprensione di questo problema?
Aggiornamento:
from Gig g inner join fetch g.gigVenue gv where g.artistId = :artistId and (g.territoryId = -1 or g.territoryId = :territoryId) order by g.gigDatetime desc
<set name="gigs" inverse="true" lazy="true" table="DSP_GIG" fetch="select">
<key>
<column name="N_VENUE_ID" precision="18" scale="0" not-null="true" />
</key>
<one-to-many class="blah.blah.Gig" />
</set>
Soluzione
Dal momento che si sta utilizzando strumentazione bytecode invece di associazione proxy (perché?) È necessario specificare "fetch" tutte le proprietà nella query:
from Gig g fetch all properties ...
I dettagli sono qui
Aggiornamento: la mappatura gigVenue
sta mettendo a lazy
no-proxy
. Ciò significa che la proprietà sarà NULL fino a quando il suo primo accessibile tramite il metodo getter. Questo viene fatto usando strumentazione bytecode e non è qualcosa che viene comunemente utilizzato. Utilizzando HQL join fetch
NON popolerà tale proprietà; è necessario specificare esplicitamente fetch all properties
come ho descritto sopra.
considerare la creazione lazy="proxy"
invece (che è in realtà il default per molti-a-uno) che inizializzare la proprietà con un oggetto proxy che contiene identificatore gigVenue
durante la selezionare iniziale, poi recuperare l'entità effettiva una volta che si accede uno dei metodi di GigVenue
. Utilizzando join fetch
in HQL lavorerà anche in questo caso, il recupero completo esempio GigVenue
durante la select iniziale.
In tal senso, l'impostazione fetch="select"
è anche discutibile; siete più probabile meglio lasciando l'impostazione predefinita join
per abilitare l'uso outer join per il recupero.
Altri suggerimenti
Strumentazione in realtà non influisce sulle query e come funzionano. Perché stai facendo esattamente l'operazione di recupero nella query? Stai cercando di accelerare le cose?
E anche una piccola domanda, nel caso in cui, come si fa a so il valore è nullo? è che tramite il debugger Java o è che, in realtà chiamando il metodo "get"? Con la strumentazione, il campo sarà tipicamente nulla, fino a che realmente chiedere il campo.