递归JPA查询?

Mik*_*zak 15 java orm recursive-query jpql jpa-2.0

JPA 2是否有任何运行递归查询的机制?

这是我的情况:我有一个实体E,它包含一个整数字段x.它也可能有类型E的子节点,通过@OneToMany映射.我想做的是通过主键找到一个E,并获得它的x值以及它所有后代的x值.有没有办法在单个查询中执行此操作?

我正在使用Hibernate 3.5.3,但我不想对Hibernate API有任何明确的依赖.


编辑:根据这一项目,Hibernate并没有具备这个功能,或者至少是在三月份没有.所以JPA似乎不太可能拥有它,但我想确定一下.

Mic*_*ker 26

使用简单的邻接模型,其中每一行包含对其父项的引用,这将引用同一表中的另一行,与JPA不能很好地协作.这是因为JPA不支持使用Oracle CONNECT BY子句或SQL标准WITH语句生成查询.没有这两个条款中的任何一个,它实际上不可能使邻接模型有用.

但是,还有其他几种可以应用于此问题的建模此问题的方法.第一个是物化路径模型.这是将节点的完整路径展平为单个列的位置.表定义扩展如下:

CREATE TABLE node (id INTEGER,
                   path VARCHAR, 
                   parent_id INTEGER REFERENCES node(id));
Run Code Online (Sandbox Code Playgroud)

插入节点树看起来像是:

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'
Run Code Online (Sandbox Code Playgroud)

因此,为了获得Node'1'及其所有子节点,查询是:

SELECT * FROM node WHERE id = 1 OR path LIKE '1.%';
Run Code Online (Sandbox Code Playgroud)

要将此映射到JPA,只需将"path"列作为持久对象的属性.但是,您必须进行簿记才能使"路径"字段保持最新状态.JPA/Hibernate不会为你做这件事.例如,如果将节点移动到另一个父节点,则必须更新父节点引用并从新父节点确定新路径值.

另一种方法称为嵌套集模型,它有点复杂.可能最好由其创始人描述(而不是由我逐字添加).

还有第三种方法称为嵌套间隔模型,但是这很大程度上依赖于存储过程来实现.

SQL这一章的第7章描述了对这个问题的更完整的解释.


99S*_*ono 6

这篇文章中的最佳答案似乎是对我的大规模解决方案.我已经不得不处理数据模型,其中出色的工程师认为在数据库领域中编写树形大亨的代码是一个好主意,例如:"Europe | Uk | Shop1 | John"以及这些表中的大量数据.不足为奇,表现形式为MyHackedTreeField LIKE'parentHierharchy%'形式的杀手.解决这类问题最终需要在树的层次结构中创建内存缓存以及其他许多...

如果您需要运行递归查询,并且您的数据量不大......让您的生活变得简单,只需加载运行计划所需的数据库字段.并在java中编写递归代码.除非你有充分的理由这样做,否则不要在数据库中创建它.

即使你拥有的数据量是巨大的,你最有可能可以细分成问题递归indepent树批次和处理那些一下午时间,而不需要一次加载所有数据.