如何在Hibernate中使用HQL选择子节点的顶级父节点?
示例: 我有ID:13的对象(网页),我想得到她的父母(在这个例子中ID为6的网页)。是否可以使用HQL?我正在使用PostgreSQL。
模型
@Entity
public class Webpage {
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "parent_id")
private Webpage parent;
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private Set<Webpage> childrens;
// getter setter
}**
答案 0 :(得分:0)
您可以使用递归获取结果,对于exp:
digoal=# create table tp(id int , childid int, info text);
CREATE TABLE
digoal=# insert into tp values (1,2,'test');
INSERT 0 1
digoal=# insert into tp values (1,3,'test');
INSERT 0 1
digoal=# insert into tp values (2,4,'test');
INSERT 0 1
digoal=# insert into tp values (4,5,'test');
INSERT 0 1
digoal=# insert into tp values (4,6,'test');
INSERT 0 1
digoal=# insert into tp values (6,7,'test');
INSERT 0 1
digoal=# insert into tp values (8,9,'test');
INSERT 0 1
digoal=# insert into tp values (8,10,'test');
INSERT 0 1
digoal=# insert into tp values (8,11,'test');
INSERT 0 1
digoal=# insert into tp values (11,13,'test');
INSERT 0 1
digoal=# insert into tp values (11,14,'test');
INSERT 0 1
digoal=# select * from tp order by id,childid;
id | childid | info
----+---------+------
1 | 2 | test
1 | 3 | test
2 | 4 | test
4 | 5 | test
4 | 6 | test
6 | 7 | test
8 | 9 | test
8 | 10 | test
8 | 11 | test
11 | 13 | test
11 | 14 | test
(11 rows)
digoal=# with recursive t as (
select id from tp where childid=7
union all
select tmp.id from tp as tmp join t on (tmp.childid=t.id)
) select row_number() over() , * from t order by 1 desc limit 1;
row_number | id
------------+----
4 | 1
(1 row)
答案 1 :(得分:0)
最终解决方案:
@Override
public Webpage getTopParentWebpage(final Webpage childrenNode) {
Validate.notNull(childrenNode);
StringBuilder sql = new StringBuilder();
sql.append("with recursive tmp_webpage(id, parent) as ( ")
.append(" values(-1::BIGINT, :childrenNodeId::BIGINT) ")
.append(" union all ")
.append(" select w.id, w.parent_id ")
.append(" from tmp_webpage as tw, webpage as w ")
.append(" where w.id = parent ")
.append(" ) ")
.append(" select * from webpage w where id = ( select t.id from tmp_webpage as t where t.parent is NULL ) ");
Query query = sessionFactory.getCurrentSession().createSQLQuery(sql.toString())
.addEntity(Webpage.class)
.setMaxResults(1)
.setLong("childrenNodeId", childrenNode.getId());
return (Webpage)query.uniqueResult();
}
SQL查询:
with recursive tmp_webpage(id, parent) as (
values(-1::BIGINT, :childrenNodeId::BIGINT)
union all
select w.id, w.parent_id from tmp_webpage as tw, webpage as w
where w.id = parent
)
select * from webpage where id = ( select t.id from tmp_webpage as t where t.parent is NULL ) ;
注意::childrenNodeId 必须绑定/替换您的子节点ID。值 -1 ,表示初始值。
我希望有帮助