我有这个原生查询:
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视图:
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 containerscontent_containers为我提供的是在每个“根”下列出所有存在的父/子关系的能力。
“Content”类可以包含一个称为“容器”的列表,其中包含更多内容。通过这种方式,我的内容可以建模为一棵树:
public class Content {
  protected List<Content> container;
  ... // More fields该查询的工作方式是将两个内容项与由Hibernate 'content_content‘创建的多对多列表映射连接起来,并使用递归查询来允许我仅选择出现在指定根目录下的内容。
问题是,当一段内容没有子项时,它根本不会被选中,因为它们在content_container查询中不是父/子关系。
我该如何解决这个问题?带有空内容c2和空多对多列表关系的“左连接”是否适用于Hibernate?
发布于 2016-06-24 17:24:08
是的,如果连接关系(cc)和子项(c2)为空,那么Hibernate会正确地将其解释为项的递归列表为空。
我必须将递归查询更改为:
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以及与之连接的原生查询:
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代码扫描列表会更好,但至少现在只需要一个查询就可以了。
https://stackoverflow.com/questions/37996318
复制相似问题