Использование простой модели смежности , где каждая строка содержит ссылку на своих родителей, которые будут ссылаться на другую строку в той же таблице, плохо взаимодействует с JPA.Это связано с тем, что JPA не поддерживает генерацию запросов с использованием предложения Oracle CONNECT BY или стандартного оператора WITH SQL.Без любого из этих двух предложений сделать Смежную модель действительно невозможно.
Однако существует несколько других подходов к моделированию этой проблемы, которые могут быть применены к этой проблеме.Первой является Материализованная модель пути .Здесь полный путь к узлу сведен в один столбец.Определение таблицы расширяется следующим образом:
CREATE TABLE node (id INTEGER,
path VARCHAR,
parent_id INTEGER REFERENCES node(id));
Вставка дерева узлов выглядит примерно так:
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'
Таким образом, чтобы получить узел '1' и всех его дочерних элементов,запрос:
SELECT * FROM node WHERE id = 1 OR path LIKE '1.%';
Чтобы отобразить это в JPA, просто сделайте столбец 'path' атрибутом вашего постоянного объекта.Однако вам придется вести бухгалтерский учет, чтобы обновлять поле «путь».JPA / Hibernate не сделает это для вас.Например, если вы переместите узел на другого родителя, вам придется обновить родительскую ссылку и определить новое значение пути из нового родительского объекта.
Другой подход называется Модель вложенного набора , что немного сложнее.Вероятно, лучше всего , описанный его создателем (а не добавленным мной дословно).
Существует третий подход, называемый Nested Interval Model, однако он имеет большую зависимость от реализации хранимых процедур.
Гораздо более полное объяснение этой проблемы описано в главе 7 Искусство SQL .