I have a search screen, using JSF, JBoss Seam, and Hibernate underneath. There are columns for A
, B
, and C
, where the relations are as follows:
A (1< --; >*) B (1< --; >*) C
Let's say A
has a List< B >
and B
has a List< C >
(both relations are one-to-many).
The UI table supports ordering by any column (ASC or DESC), so I want the results of the query to be ordered. This is the reason I used Lists in the model.
However, I got an exception that Hibernate cannot eagerly fetch multiple bags (it considers both lists to be bags). There is an interesting blog post here, and they identify the following solutions:
- Use @IndexColumn` annotation (there is none in my DB, and what's more, I want the position of results to be determined by the ordering, not by an index column)
- Fetch lazily (for performance reasons, I need eager fetching)
- Change List to Set
I changed the List to Set, which by the way is more correct, model-wise.
- First, if don't use @OrderBy, the
PersistentSet
returned by Hibernate wraps aHashSet
, which has no ordering. So, when I iterate over it in the UI, the order is random, whatever ordering the database did. - Second, If I do use @OrderBy, the
PersistentSet
wraps aLinkedHashSet
, which has ordering, and is what I would like. However, theOrderBy
property is hardcoded, and takes precedence over whatever ordering I set both using Collections (link) or HQL (link). As such, all other ordering I request through the UI comes after it.
I tried again with Sets
, and used SortedSet
(and its implementation, TreeSet
), but I have some issues:
I want ordering to take place in the DB, and not in-memory, which is what
TreeSet
does (either through a Comparator, or through the Comparable interface of the elements).I found that there is the Hibernate annotation @Sort, which has a
SortOrder.UNSORTED
and you can also set a Comparator. I still haven't managed to make it compile, but I am still not convinced it is what I need.
One of the requirements is for the sorting to take place in the DB.
Created a simple Maven project and committed it as a Google Code project. This is my personal playground for the problem.