Estoy escribiendo una función en hibernación para inicializar recursivamente todas las propiedades del objeto recursivamente para que se cargue el gráfico completo del objeto.Inicialización recursiva de Hibernate
tengo dos escenarios complejos donde i necesidad de utilizar este objeto compuesto
1) auto como categoría y la categoría sub ...
@Entity
public class Category {
@Column(nullable = false, length = 50)
@NotNull
@Size(max = 50, message = "{50}")
protected String name;
@ManyToOne(targetEntity = Category.class, fetch = FetchType.LAZY, optional = true)
private Category parentCategory;
}
2) complejo gráfico de objetos que tiene gran cantidad de objeto a inicializar antes de que pueda ser utilizado.
problema es que no puedo usar la búsqueda ansiosa porque necesito este gráfico de objeto completo solo en casos selectivos, y quiero tener código general para no tener que escribir consultas HQL para objetos.
he escrito algo de código parcial para esto,
public void recursiveInitliaze(Object obj) throws Exception {
if(!Hibernate.isInitialized(obj))
Hibernate.initialize(obj);
PropertyDescriptor[] properties = PropertyUtils.getPropertyDescriptors(obj);
for (PropertyDescriptor propertyDescriptor : properties) {
Object origProp = PropertyUtils.getProperty(obj, propertyDescriptor.getName());
if (origProp != null) {
this.recursiveInitliaze(origProp);
}
if (origProp instanceof Collection && origProp != null) {
for (Object item : (Collection) origProp) {
this.recursiveInitliaze(item);
}
}
}
}
pero tiene un problema, que termina en stackoverflow de invocación de método debido a las relaciones bidireccionales. Entonces, ¿cómo detectar que existe una relación bidireccional o hay alguna forma mejor de implementar esto?
Creo que el perfil fetch también puede ayudar, pero aún así quiero intentar implementar esto si es posible, ya que la configuración del perfil de búsqueda en la etapa actual del proyecto es difícil.
isInitialised ya he utilizado en la lógica, pero el problema que estoy enfrentando es con relación bidireccional, por ejemplo, si la clase A se asocia con B y ambos contienen referencias entre sí, siempre lo obtendré como propiedad y terminará en una llamada recursiva infinita. –
isInitialised le da verdadero después de que lo haya inicializado una vez y no necesitará realizar una cascada después, ningún bucle infinito. ¿Ha comprobado si initialize() hace lo que quiere? – Firo
sí initialize() solo inicializa el objeto actual y no se conecta en cascada. y no puedo depender de isInitialised porque si tengo una jerarquía de objetos como A contiene B, B contiene C, entonces incluso B se inicializa C podría no ser así, tiene que ir al objeto B encontrar C e inicializar. El problema con mi código es que si C contiene una referencia posterior a B, intenta invocar la función nuevamente. –