Между 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-ной записи – комментарии.