En primer lugar, suponiendo que en esta jerarquía un "padre" puede tener más de un hijo, el campo father
debe anotarse como @ManyToOne
.
Si usted tiene un campo que todos los miembros de una cuota de árbol, o si el árbol contiene toda la tabla, entonces es posible hacerlo con la APP de una manera eficiente, aunque no a través de una sola consulta JPA .
sólo hay que precargar todos los miembros del árbol, y luego recorrer el árbol:
@Entity
@Table(name="categories")
public class Category {
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
@SequenceGenerator(name="sequence", sequenceName="categories_pk_seq", allocationSize=1)
@Column(name="id")
private Long id;
@Column
private String name;
@ManyToOne
@JoinColumn(name="idfather")
private Category father;
@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE},
fetch = FetchType.LAZY,
mappedBy = "idfather")
@OrderBy("name")
private List<Category> subCategories;
}
Aviso @OrderedBy
la anotación en el campo subcategorías.
Ahora puede obtener todo el árbol cargando primero todas las categorías en una lista desordenada, solo para que todas estén en la memoria y luego atraviesen el árbol.
public List<Category> getTree() {
List<Category> jumbled =
entityManager.createQuery("from Category", Category.class).getResultList();
Category root = null;
for(Category category : jumbled) {
if(category.getFather() == null) {
root = category;
break;
}
}
List<Category> ordered = new ArratList<Category>();
ordered.add(root);
getTreeInner(root, ordered);
}
private void getTreeInner(Category father, List<Category> ordered) {
for(Category child : father.getSubCategories()) {
ordered.add(child);
getTreeInner(child, ordered);
}
}
sólo estoy aprendiendo APP mí en este momento, así que es posible que falte algo fundamental, pero este enfoque parece funcionar para mí.
En su caso, supongo que necesita una relación de padres a hijos. Así que algo como '@OneToMany @JoinColumn (name =" idfather ") @OrderBy (value =" name ") private List children' te ayudará. Y luego buscar una categoría raíz cargará todo el árbol. –
@dma_k Ya había tenido la misma Idea y después de saber que no era posible la consulta JPA que estaba haciendo de esta manera, gracias – Javi
¿Pueden compartir con nosotros también el código Java, que realmente carga el árbol? Me pregunto cómo construyes/ejecutas la consulta JPA. También creo que si la capa de persistencia carga el árbol ejecutando una consulta para un nodo del árbol, debería saber cómo recuperar los elementos secundarios. Me pregunto cómo la extensión 'CONNECT BY PRIOR' de Oracle puede ayudarte aquí. –