hibernate ordering a set

hibernate ordering a set  using -'java,hibernate,order,criteria'

I have a class Person who has a set of Books. It is not meaningful in the particular case to have an ordered or sorted collection.

Say now that I have a search page with a table showing the join of Person and Book. I want to be able to sort the results by fields from both Person AND Book, and then get a List from Hibernate, and iterate over it.

Because the collection is a Set, the ordering of the Books has vanished (PersistentSet of Hibernate wraps a HashSet of Books, which is not ordered).

So, with this approach I cannot have results also ordered by Book fields.

If I change the collection from Set to List, my model is semantically incorrect. There is no meaning for keeping order in the model.

Is there an approach to keep the ordering of Books? Perhaps there is a way for the PersistentSet to wrap a LinkedHashSet (which is ordered), where the order is defined by my search Criteria?


asked Oct 19, 2015 by abhi
0 votes
1 view

4 Answers

0 votes

Hibernate supports mapping a collection as a SortedSet. In your mappings you basically just need to specify an order-by clause. Take a look at this chapter in the reference manual.

answered Oct 19, 2015 by rajeshujade
0 votes

Like said Markos Fragkakis

unfortunately order-by in the mapping (or @OrderBy) takes precedence, which makes the ordering set by the Criteria useless.

But you must set @Order if you want to have the Set ordered.

You can still use HQL instead ( tested on hibernate 3.3.2.GA ) who order firstly by the order in the hql query :

    @Table(name = "Person")
    public class Person  {

        @Column(name = "ID_PERSON", unique = true, nullable = false, precision = 8, scale = 0)
        private Long id;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
        private Set books = new HashSet(0);

        public Person() {

        public Long getId() {
            return this.id;

        public void setId(Long id) {
            this.id = id;

      public Set getBooks() {
            return this.books;

        public void setBooks(Set books) {
            this.books = books;


       *  hql Version 
       *  Result in : 
       *  order by
       *      book1_.TITLE asc,
       *      book1_.ID_BOOK asc  

        public Person getFullPerson(Long idPerson) {

            StringBuilder hqlQuery =  new StringBuilder();
            hqlQuery.append("from Person as p ");
            hqlQuery.append("left join fetch p.books as book ");
            hqlQuery.append("where p.id = :idPerson ");
            hqlQuery.append("order by book.title ");
            Query query = createQuery(hqlQuery.toString());
            query.setLong("idPerson", id);
            return uniqueResult(query);


       *  criteria  Version // not usable 
       *  Result in : 
       *  order by
       *      book1_.ID_BOOK asc,
       *      book1_.TITLE asc  

    public Person getFullPersonCriteria(Long idPerson) {

        Criteria criteria = ...
        criteria.add(Restrictions.eq("id", idPerson));
        criteria.createAlias("books", "book", CriteriaSpecification.LEFT_JOIN);
            return criteria.uniqueResult();
answered Oct 19, 2015 by vickeykumar66
0 votes

This is an in-memory sort that will take care of duplicates in the join table.

  @JoinTable(name = "person_book", joinColumns = @JoinColumn(name = "person_id"),
             inverseJoinColumns = @JoinColumn(name = "book_id"))
  @Sort(type = SortType.COMPARATOR, comparator = MyBookComparator.class)
  private SortedSet books;
answered Oct 19, 2015 by tseetha
0 votes

not sure if i got the question right but if you just want an ordererd version of your list you can just sort it with the java.util.Collections class and a Comparator. Maybe you want to make a transient Method on your pojo like this:

public List getBooksASC()
    Collections.sort(this.books, new BookSorter.TitelASCSorter());
    return this.books;

Just write a Class which implements Comparator.

answered Oct 19, 2015 by pradip.bhoge