Attualmente sto spostando un'applicazione (funzionante) dall'utilizzo di EclipseLink a Hibernate JPA, principalmente è andata abbastanza bene, ma sto trovando una cosa che non posso spiegare, e posso anche Pensa a qualsiasi buon termine di ricerca!Hibernate JPA - ManyToOne relationship not populated
Fondamentalmente, ho quattro entità, con uno-a-molti formando una catena:
EntityA ha una lista di EntityB di, ognuno dei quali ha una lista di EntityC di, ognuna delle quali ha un elenco di EntityD di
ciascuno di questi ha quindi una relazione molti-a-uno in senso contrario, quindi:
EntityD ha un EntityC, che ha un EntityB, che ha un EntityA.
Che è (fortemente ridotto per chiarezza):
@Entity
public class EntityA {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityA")
private List<EntityB> entityBList;
...
}
@Entity
public class EntityB {
@OneToMany (cascade = CascadeType.All, mappedBy = "entityB")
private List<EntityC> entityCList;
@JoinColumn (name = "ENTITY_A", referencedColumnName = "ENTITY_A_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityA entityA;
}
@Entity
public class EntityC {
@OneToMany (cascade = CascadeType.ALL, mappedBy = "entityC")
private List<EntityD> entityDList;
@JoinColumn (name = "ENTITY_B", referencedColumnName = "ENTITY_B_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityB entityB;
}
@Entity
public class EntityD {
@JoinColumn (name = "ENTITY_C", referencedColumnName = "ENTITY_C_ID")
@ManyToOne (cascade = CascadeType.PERSIST, optional = false)
private EntityC entityC;
}
ottengo un'EntityA dal database (guardando in su per la sua chiave primaria), e quindi ottenere un'istanza EntityA ben popolato, con un PersistentBag per il mio List<EntityB>
. Vedo un carico pigro che accade quando denuncio quello List<EntityB>
e lo stesso si ripete per ottenere EntityC dall'entitàB.
A questo punto, tutto è come mi aspetto, ho un EntityA, B e C tutti completamente popolati con i valori dal database, ma poi cerco di ottenere il mio EntityD, da EntityC, e scoprire che è null.
Il mio gestore di entità è ancora aperto e attivo a questo punto, e anche se lo guardo nel debugger subito dopo aver ottenuto EntityA, posso camminare attraverso le relazioni, fino a EntityC, e di nuovo vedere l'entitàDList 'come nulla.
L'unica soluzione che ho trovato finora è quello di utilizzare:
EntityManager.refresh(entityC);
che popola tutti i suoi elementi, tra cui una PersistentBag pigramente-caricato per l'entityDList.
Quindi, la mia ipotesi è che Hibernate stia compilando solo i 2 livelli di profondità (o 3, a seconda di come si conta), e rinunciando dopo, anche se non capisco davvero perché sarebbe. Ha senso per qualcuno?
Esiste una soluzione diversa da .refresh? Qualche tipo di configurazione o valore di annotazione che renderà Hibernate popolare i riferimenti fino in fondo?
Qual è il valore impostato per il parametro di configurazione di ibernazione "max_fetch_depth"? –