Если ваша база данных не связана с java-кодом, выполняющим эти запросы, вероятно, узким местом является производительность для запроса на узел, даже если это просто запрос на внутренний узел.Поскольку вам известны максимальные уровни дерева (для примера предположим 3), следующее должно извлечь все дерево в одном запросе:
from Node n1
left join n1.children as n2
left join n2.children as n3
left join n3.children as n4
Недостатком этого метода является то, чтоresultset будет повторять данные для каждого внутреннего узла для каждого из его потомков, т.е. взятая полоса умножается на количество уровней дерева.Если это проблема, потому что у вас много уровней, вы можете включить пакетную выборку для этой коллекции или даже сделать что-то подобное вручную:
List<Node> border = Collections.singletonList(rootNode);
while (!border.isEmpty()) {
List<Integer> ids = new ArrayList<Integer>();
for (Node n : border) {
ids.add(n.getId());
}
// initialize the children collection in all nodes in border
session.createQuery("from Node n left join n.children where n.id in ?").setParameter(0, ids).list();
List<Node> newBorder = new ArrayList<Node>();
for (Node n : border) {
newBorder.addAll(n.getChildren());
}
border = newBorder;
}
Это выдаст столько запросов, сколько уровней в дереве.и передать данные для каждого узла дважды.(Некоторые базы данных ограничивают размер встроенного предложения. Тогда вам придется пакетировать в пределах уровня)