首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当父对象没有子项(左连接)时,如何使用Hibernate获取递归关系?

当父对象没有子项(左连接)时,如何使用Hibernate获取递归关系?
EN

Stack Overflow用户
提问于 2016-06-23 23:48:51
回答 1查看 1.3K关注 0票数 0

我有这个原生查询:

代码语言:javascript
运行
复制
SELECT c1.*, c2.*, cc.* FROM content c1, content c2, content_content cc, content_containers r
    WHERE c1.id = r.parent
    AND c2.id = r.child
    AND cc.content_col_id = r.parent
    AND r.root = :id

其中content_containers是递归Postgres视图:

代码语言:javascript
运行
复制
CREATE OR REPLACE VIEW content_containers AS
WITH RECURSIVE containers(parent, child, index, root, depth) AS ( 
    SELECT content_col_id, content_id, container_index, content_col_id, 1
        FROM content_content
    UNION ALL
    SELECT c.child, l.content_id, l.container_index, root, depth + 1
        FROM containers c, content_content l
        WHERE c.child = l.content_col_id
)  
SELECT parent, child, index, root, depth
    FROM containers

content_containers为我提供的是在每个“根”下列出所有存在的父/子关系的能力。

“Content”类可以包含一个称为“容器”的列表,其中包含更多内容。通过这种方式,我的内容可以建模为一棵树:

代码语言:javascript
运行
复制
public class Content {
  protected List<Content> container;
  ... // More fields

该查询的工作方式是将两个内容项与由Hibernate 'content_content‘创建的多对多列表映射连接起来,并使用递归查询来允许我仅选择出现在指定根目录下的内容。

问题是,当一段内容没有子项时,它根本不会被选中,因为它们在content_container查询中不是父/子关系。

我该如何解决这个问题?带有空内容c2和空多对多列表关系的“左连接”是否适用于Hibernate?

EN

回答 1

Stack Overflow用户

发布于 2016-06-24 17:24:08

是的,如果连接关系(cc)和子项(c2)为空,那么Hibernate会正确地将其解释为项的递归列表为空。

我必须将递归查询更改为:

代码语言:javascript
运行
复制
CREATE OR REPLACE VIEW content_containers AS
WITH RECURSIVE containers(parent, child, index, root, depth) AS ( 
    SELECT c.id, cc.content_id, cc.container_index, c.id, 1 FROM content c
       LEFT JOIN content_content cc
       ON cc.content_col_id = c.id
    UNION ALL
    SELECT c.child, l.content_id, l.container_index, root, depth + 1
        FROM containers c, content_content l
        WHERE c.child = l.content_col_id
)  
SELECT parent, child, index, root, depth
    FROM containers

以及与之连接的原生查询:

代码语言:javascript
运行
复制
SELECT c1.*, c2.*, cc.* FROM content c1
    JOIN content_containers r ON c1.id = r.parent
    LEFT JOIN content c2 ON c2.id = r.child
    LEFT JOIN content_content cc ON cc.content_col_id = r.parent AND cc.content_id = r.child
    WHERE r.root = :id
    ORDER BY r.depth

这意味着递归查询返回一个根和一个父项,即使没有子项也是如此,因此始终可以在不是左连接的情况下连接到它。然后,只有当子项和列表可用时,才会在本机查询中使用左联接来选择子项和列表。

对此感到非常满意,可以连接到通用递归查询,以便在所有类型的查询中重用它。

我使用了按深度排序,这样根项目就会出现在顶部,然后可以从结果列表中选择作为项目0。我不确定是这样,还是用Java代码扫描列表会更好,但至少现在只需要一个查询就可以了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37996318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档