HQL рекурсия, как мне это сделать? - PullRequest
15 голосов
/ 21 марта 2010

У меня есть древовидная структура, где у каждого Node есть родитель и Set<Node> children. Каждый узел имеет String title, и я хочу сделать запрос, в котором я выбираю Set<String> titles, являясь заголовком этого узла и всех родительских узлов. Как мне написать этот запрос?

Запрос для одного заголовка такой, но, как я уже сказал, я бы хотел, чтобы он был расширен для всей ветви родителей.

SELECT node.title FROM Node node WHERE node.id = :id

Приветствия

Nik

Ответы [ 2 ]

14 голосов
/ 21 марта 2010

Вы не можете делать рекурсивные запросы с HQL. Смотрите это . И, как указано там, это даже не стандартный SQL. У вас есть два варианта:

  • написать рекурсивный нативный для конкретного поставщика SQL-запрос
  • сделать несколько запросов. Например:

    // obtain the first node using your query
    while (currentNode.parent != null) {
       Query q = //create the query
       q.setParameter("id", currentNode.getParentId());
       Node currentNode = (Node) q.getSingleResult();
       nodes.add(currentNode); // this is the Set
    }
    

Я бы точно выбрал второй вариант.

9 голосов
/ 19 ноября 2010

Несмотря на то, что невозможно написать рекурсивный запрос, который вы запрашиваете, есть возможность получить иерархию с помощью HQL; это позволит вам, по крайней мере, пройтись по дереву в памяти, не обращаясь к базе данных для каждого уровня.

select n from Node n
left join fetch n.Children
...