Между JPA аннотациями @OrderBy и @OrderColumn есть существенное различие.
@OrderBy — аналог обычной SQL команды ORDER BY. Здесь всё понятно. Например, у вас отношение один ко многим. Для примера возьмём сущность «Новость» и к ней привязано несколько «Комментариев». На уровне объектной модели, это значит, что у вас есть объект класса News, у которого есть метод который возвращает список комментариев:
+-----------------------------+
|News |
|-----------------------------|
|-----------------------------|
|+getComments(): List<Comment>|
+-----------------------------+
+-----------------+
|Comment |
|-----------------|
|-----------------|
|+getNews(): News |
+-----------------+
В таком случае, мы должны указать в классе News:
// тут аннотации
public class News {
@OneToMany(targetEntity = Comment.class, mappedBy="news")
@OrderBy(value="pubdate desc")
private List comments;
// дальше какой-то код еще ...
}
Причем сортировка должна быть сделана на уровне БД, через ORDER BY выражение. В данном примере мы сортируем комментарии, по дате их публикации (поле pubdate).
@OrderColumn — задает другой способ оказания порядка (материализованный). В этом случае порядковый номер записи указывается явно в таблице. В Hibernate была аналогичная аннотация @IndexColumn , ее использовали до выхода JPA 2.0. Сейчас по возможности лучше вместо @IndexColumn использовать @OrderColumn. В Hibernate поддерживаются обе.
Разберём пример. Допустим, у вас опять используется отношение один ко многим, но в этом случае возьмем сущность «Дом» в котором живут несколько «Постояльцев». В этом доме в 1-ом номере остановились Ивановы, во 2-ом Петровы, с 3 и 4 — пустуют, в 5 — Кузнецовы.
0 - null
1 - Ивановы
2 - Петровы
3 - null
4 - null
5 - Кузнецовы
Для того, чтобы сохранить информацию кто в каком номере живет, мы явно указываем в табличке с жильцами номер комнаты (поле room).
+-------------------------------+
|House |
|-------------------------------|
|-------------------------------|
|+getResidents(): List<Resident>|
+-------------------------------+
+----------------------+
|Resident |
|----------------------|
| room:Integer |
+----------------------+
В таком случае, мы пишем в классе House:
// аннотации
public class House {
// ...
@OneToMany(targetEntity = Resident.class, mappedBy="house")
@OrderColumn(name="room")
private List residents;
}
Внимание! Теперь самое важное. Если в данном случае использовать OrderColumn, то у нас будет список в котором будут дыры! С другой стороны, мы можем сразу по порядковому номеру в списке определить номер комнаты.
// жители:
List list = house.getResidents();
// 2 - Петровы
Resident petrovy = list.get(2) ;
Отличие от OrderBy фундаментальное.
Если вы неправильно спроектируете зависимости и укажите в первом примере (новости — комментарии) вместо OrderBy аннотацию OrderColumn по «дате публикации», то у вас может возникнуть как явная ошибка, так и неявная ошибка, например по причине конвертации поля даты в число. Зависит от БД и ORM.
Например, в MySQL + Hibernate это может сработать следующим образом. Дата публикации «01.01.2011» — преобразуется в число «2011», в итоге получаем список из null-ов, а в конце после 2011-ной записи — комментарии.