Zunächst einmal unter der Annahme, dass ein "Vater" in dieser Hierarchie mehr als ein Kind haben kann, dann sollte das Feld father
mit @ManyToOne
kommentiert werden.
Wenn Sie ein Feld haben, das alle Mitglieder eines Baums teilen, oder wenn der Baum die gesamte Tabelle enthält, dann ist möglich, es mit JPA in einer effizienten Weise zu tun, obwohl nicht durch eine einzelne JPA-Abfrage .
Sie müssen nur alle Mitglieder des Baumes Prefetch und dann durchqueren den Baum:
@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;
}
Beachten Sie die @OrderedBy
Anmerkung auf dem Subkategorien Feld.
Jetzt können Sie den gesamten Baum erhalten, indem Sie zuerst alle Kategorien in eine verwirrende Liste laden, nur damit sie alle im Speicher sind, und dann den Baum durchqueren.
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);
}
}
Ich bin nur JPA mich jetzt lernen, damit ich etwas von entscheidender Bedeutung fehlt, aber dieser Ansatz scheint für mich zu arbeiten.
In Ihrem Fall nehme ich an, dass Sie Eltern-Kind-Beziehung benötigen. So etwas wie @OneToMany @JoinColumn (Name = "IDFather") @OrderBy (Wert = "Name") private Liste Kinder werden Ihnen helfen. Wenn Sie dann eine Stammkategorie abrufen, wird der gesamte Baum geladen. –
@dma_k Ich hatte bereits die gleiche Idee und nachdem ich wusste, dass es nicht passierbar war, versuchte ich die JPA-Abfrage auf diese Weise. – Javi
Kannst du uns bitte auch den Java-Code mitteilen, der den Baum tatsächlich lädt? Ich frage mich, wie Sie JPA-Abfrage erstellen/ausführen. Ich denke auch, dass, wenn der Persistenz-Layer den Baum lädt, indem er eine Abfrage für einen Baum-Knoten ausführt, er wissen sollte, wie er Kinder abruft. Ich frage mich, wie Oracles Erweiterung "CONNECT BY PRIOR" Ihnen hier helfen kann. –