Verwendung des einfachen Adjazenzmodells wo jede Zeile einen Verweis auf ihre Eltern enthält, die sich auf eine andere Zeile in der gleichen Tabelle beziehen, funktioniert nicht gut mit JPA. Dies liegt daran, dass JPA keine Unterstützung für das Generieren von Abfragen unter Verwendung der Oracle CONNECT BY-Klausel oder der SQL-Standard-WITH-Anweisung bietet. Ohne eine dieser beiden Klauseln ist es nicht wirklich möglich, das Adjazenzmodell nützlich zu machen.
Es gibt jedoch ein paar andere Ansätze zur Modellierung dieses Problems, die auf dieses Problem angewendet werden können. Das erste ist das Materialized Path Model. Hier wird der vollständige Pfad zum Knoten in eine einzelne Spalte abgeflacht. Die Tabellendefinition ist wie so erweitert:
CREATE TABLE node (id INTEGER,
path VARCHAR,
parent_id INTEGER REFERENCES node(id));
einen Baum von Knoten einzufügen sieht etwas, was wie:
INSERT INTO node VALUES (1, '1', NULL); -- Root Node
INSERT INTO node VALUES (2, '1.2', 1); -- 1st Child of '1'
INSERT INTO node VALUES (3, '1.3', 1); -- 2nd Child of '1'
INSERT INTO node VALUES (4, '1.3.4', 3); -- Child of '3'
So Knoten ‚1‘ und alle seine Kinder bekommen die Abfrage:
Um dies JPA zuzuordnen, machen Sie einfach die 'Pfad' Spalte ein Attribut Ihres persistenten Objekts. Sie müssen jedoch die Buchhaltung führen, um das Feld "Pfad" auf dem neuesten Stand zu halten. JPA/Hibernate wird dies nicht für Sie tun. Z.B. Wenn Sie den Knoten auf ein anderes Elternelement verschieben, müssen Sie sowohl den übergeordneten Verweis aktualisieren als auch den neuen Pfadwert aus dem neuen übergeordneten Objekt ermitteln.
Der andere Ansatz heißt verschachtelte Set-Modell, die etwas komplexer ist. Wahrscheinlich am besten described von seinem Urheber (anstatt von mir wortwörtlich hinzugefügt).
Es gibt einen dritten Ansatz, der als verschachteltes Intervallmodell bezeichnet wird, das sich jedoch stark auf gespeicherte Prozeduren stützt, die implementiert werden müssen.
Eine ausführlichere Erklärung dieses Problems ist in Kapitel 7 von The Art of SQL beschrieben.
Das ist alles viel komplexer als das, was ich suchte, aber danke für die informative Antwort. Es gibt auch eine einfachere Alternative zum materialisierten Pfadmodell - jeder Knoten speichert die ID des Wurzelknotens des Baumes, zu dem er gehört. Das bedeutet, dass Sie nur den Wurzelknoten als Startpunkt der Abfrage verwenden können, aber in meinem speziellen Fall ist das kein Problem - das werde ich wahrscheinlich tun. –
Sie können Adjazenzlisten verwenden, die über JPA verwaltet werden, aber eine systemeigene Abfrage verwenden, um rekursive SQL-Funktionen zu verwenden. Es wäre ein bisschen eklig und nicht tragbar, aber es wäre etwas von einem Besten beider Welten. Verschachtelte Sätze sind zwar portabel, aber knifflig und eignen sich für einige ziemlich häufige Arten von Abfragen nicht besonders gut. –
Hat sich mit JPA 2.0 etwas geändert ... Zum Beispiel habe ich eine Native NamedQuery verwendet, um in meiner Abfrage eine CONNECT BY-Klausel zu haben. Ich habe es versucht und es gibt die Kinder zurück, aber nicht in einer hierarchischen Liste Form ... Nur flache Kinder. Irgendwelche Ideen? – SoftwareSavant