Java JPA:导致1+N选择的构造函数表达式

Java JPA:导致1+N选择的构造函数表达式,java,hibernate,jpa,Java,Hibernate,Jpa,遵循此处列出的建议:实现以下查询: SELECT new x.y.z.TreeInfo(t, count(l.id)) FROM Tree t LEFT JOIN t.branches b LEFT JOIN b.leaves l GROUP BY t.id 目标是在一次查询中获得整个树对象和数据库中的叶数。现在,它在第一个查询中获取计数和树ID,然后发出一个额外的查询来加载每个树。有没有办法告诉它在第一次查询中获取整个树对象?JPA是这份工作的错误工具吗 我想做的等效SQL是: select

遵循此处列出的建议:实现以下查询:

SELECT new x.y.z.TreeInfo(t, count(l.id))
FROM Tree t LEFT JOIN t.branches b LEFT JOIN b.leaves l
GROUP BY t.id
目标是在一次查询中获得整个树对象和数据库中的叶数。现在,它在第一个查询中获取计数和树ID,然后发出一个额外的查询来加载每个树。有没有办法告诉它在第一次查询中获取整个树对象?JPA是这份工作的错误工具吗

我想做的等效SQL是:

select *, (select count(*) 
          from leaf l join branch b on l.parentid = b.id
          where b.parentid = t.id)
from tree t

在展示更多的代码和映射之前,很难看出这里的问题是什么。问题可能是,例如,通过获取树选择new TreeInfo t。。。从树上。。。通过急切地获取对象图,最终加载整个树

但是,一般来说,从数据库中获取树需要多次查询,因为您不知道最长分支包含多少节点,因此不知道需要查询多少次子节点。JPA不是这里的问题

解决此问题有多种策略:

您可以将树建模为一个单独的实体—您似乎已经这样做了—并且在树中的每个节点中都有一个指向树的外键,而不仅仅是根节点。现在,您可以一次性获取树的所有节点,并让hibernate通过加载父节点和命中会话缓存来构造树结构。 可以在每个节点中以ID字符串的形式冗余存储每个节点的路径。这使得获取子树变得很容易。当结构发生变化时,很难进行更新,但这通常不是必需的。现在,通过选择路径以根节点ID开头的所有节点,可以选择树中的所有节点。您必须标记叶节点并在标记上过滤以进行计数,或者在内存中进行计数。 您可以看到,完成所需操作的唯一方法是向节点添加冗余数据

无论哪种方式,要在SQL中计算树中的叶子数,您都可以执行以下操作:


选择count*from node n left outer join node c on c.parent_id=n.id,其中c.id为null

谢谢您的回复。为了澄清,我实际上不需要或想要节点,只需要计数。每棵树有几千片叶子,因此装载它们是浪费。我的问题中的查询是作为select tree\u id执行的,count leaves子查询来自tree。然后它返回并按id选择每棵树。我不知道如何让它选择树对象的所有属性,就像我说的从树中选择一样。尝试在没有构造函数查询的情况下进行相同的查询。