bingo! seems like i've read over the subselect feature multiple times.
this is still not the best solution i could think of, but from my point of view, the overhead is acceptable compared the the alternatives.
thanks for the hint!
for those of you who are interested in some performance comparsion:
i used a small tree with 4 levels, each intermediate node has 10 childnode (so i have 1111 entites)
the pure database-timings were:
incremental traversal (without nested-set)
1111*30ms = 33330 ms
single nested-set-select with join fetch:
4900 ms
single nested-set-select for all tree-nodes plus second select with subselect for children-collection
350 ms + 490 ms = 840 ms
so using the subselect feature did a huge performance improvement and the advantage will rise the bigger the tree gets.
if hibernate would have internal knowlegde of the nested tree model, it could avoid the second subselect query at all, so reading the whole tree could take only half the time. but i doubt we'll see a tree-association-type in hibernate soon ;-)
but there is one final optimization that could be possible.
for the subselect hibernate creates a query like:
Code:
select n.parent_id, n.id, n.* from Node n where n.parent_id in (select id from Node where n.left >= x and n.right <= y)
since i know that all nodes were loaded before, it would be sufficient to execute
Code:
select n.parent_id, n.id from Node n where n.parent_id in (select id from Node where n.left >= x and n.right <= y)
in my example this would reduce the load-time of the subselect query from 490ms to 330ms.
i thought using @LazyToOne(LazyToOneOption.PROXY) should do this, but
the subselect-query stayed the same. is it possible to suppress the relaoding of data for the subselect, or do i have to live with that?
thanks again for you help (and for hibernate of course)
andi