Actualmente estoy moviendo una aplicación (de trabajo) de usar EclipseLink a Hibernate JPA, en su mayoría ha ido bastante bien, pero estoy encontrando una cosa que no puedo explicar, y también puedo ¡No pienses en ningún buen término de búsqueda!Hibernate JPA - Relación ManyToOne no poblada
Básicamente, tengo cuatro entidades, con relaciones de uno-a-muchos formando una cadena:
EntityA tiene una lista de EntityB de, cada uno de los cuales tiene una lista de EntityC de, cada uno de los cuales tiene una lista de EntityD de
cada uno de los que entonces tiene una relación muchos-a-uno en la otra dirección, por lo que:
EntityD tiene una EntityC, que tiene una EntityB, que tiene una EntityA.
que está (muy reducido para mayor claridad):
@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;
}
Obtengo un EntityA de la base de datos (mirando hacia arriba por su clave primaria), y por lo tanto obtener una instancia EntityA muy bien poblada, con una PersistentBag de mi List<EntityB>
. Veo una carga lenta sucediendo cuando desreferenciamos ese List<EntityB>
, y lo mismo se repite para obtener EntityCs de EntityB.
En este momento, todo es como esperaba, tengo una EntityA, B y C completamente llena con los valores de la base de datos, pero luego trato de obtener mi EntityD, desde EntityC, y encuentro que es nulo.
Mi administrador de entidades todavía está abierto y activo en este punto, e incluso si lo miro en el depurador inmediatamente después de obtener EntityA, puedo recorrer las relaciones, en cuanto a EntityC, y volver a ver el 'entityDList 'como nulo.
La única solución que he encontrado hasta ahora es utilizar:
EntityManager.refresh(entityC);
que puebla todos sus elementos, incluyendo un PersistentBag cargado con pereza-para la entityDList.
Entonces, supongo que Hibernate solo está llenando las referencias 2 niveles de profundidad (o 3, dependiendo de cómo cuentes), y renunciar después de eso, aunque realmente no entiendo por qué sería eso. ¿Eso tiene sentido para alguien?
¿Hay alguna otra solución que la .refresh? ¿Algún tipo de valor de configuración o anotación que hará que Hibernate llene las referencias hasta el final?
¿Cuál es el valor establecido para el parámetro de configuración de hibernación "max_fetch_depth"? –