使用简单的邻接模型,其中每一行都包含对其父级的引用,该父级将引用同一表中的另一行,这与 JPA 不能很好地合作。这是因为 JPA 不支持使用 Oracle CONNECT BY 子句或 SQL 标准 WITH 语句生成查询。如果没有这两个子句中的任何一个,就不可能真正使邻接模型有用。
但是,还有一些其他方法可以对这个问题进行建模,可以应用于这个问题。第一个是物化路径模型。这是节点的完整路径被展平为单列的地方。表定义扩展如下:
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,只需将“路径”列设置为持久对象的属性。但是,您必须进行簿记以使“路径”字段保持最新。 JPA/Hibernate 不会为您执行此操作。例如。如果将节点移动到不同的父节点,则必须同时更新父引用并确定新父对象的新路径值。
另一种方法称为嵌套集模型,它有点复杂。可能是其创始人最好的described(而不是我逐字添加)。
还有第三种方法称为嵌套区间模型,但是这种方法严重依赖存储过程来实现。
The Art of SQL 的第 7 章对此问题进行了更完整的解释。