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
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 :
@Entity
@Table(name = "Person")
public class Person {
@Id
@Column(name = "ID_PERSON", unique = true, nullable = false, precision = 8, scale = 0)
private Long id;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
@OrderBy
private Set<Book> books = new HashSet<Book>(0);
public Person() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Set<Book> getBooks() {
return this.books;
}
public void setBooks(Set<Book> books) {
this.books = books;
}
}
/**
* hql Version
*
* Result in :
* order by
* book1_.TITLE asc,
* book1_.ID_BOOK asc
**/
@Override
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
**/
@Override
public Person getFullPersonCriteria(Long idPerson) {
Criteria criteria = ...
criteria.add(Restrictions.eq("id", idPerson));
criteria.createAlias("books", "book", CriteriaSpecification.LEFT_JOIN);
criteria.addOrder(Order.asc("book.title"));
return criteria.uniqueResult();
}
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.
This is an in-memory sort that will take care of duplicates in the join table.
@OneToMany
@JoinTable(name = "person_book", joinColumns = @JoinColumn(name = "person_id"),
inverseJoinColumns = @JoinColumn(name = "book_id"))
@Sort(type = SortType.COMPARATOR, comparator = MyBookComparator.class)
private SortedSet<BookEntity> books;
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:
@Transient
public List<Book> getBooksASC()
{
Collections.sort(this.books, new BookSorter.TitelASCSorter());
return this.books;
}
Just write a Class which implements Comparator.