@OrderBy и @OrderColumn
Обе JPA-аннотации задают порядок коллекции, но хранят и поддерживают его по-разному.
@OrderBy
@OrderBy сортирует коллекцию при загрузке по persistent-атрибутам сущности.
@Entity
class PurchaseOrder {
@Id
private Long id;
@OneToMany(mappedBy = "order")
@OrderBy("price DESC, id ASC")
private List<OrderItem> items;
}Строка использует имена Java-атрибутов entity (price, id), а не произвольный SQL и не обязательно имена колонок. Порядок вычисляется из данных; отдельная позиция не хранится.
Если значения price меняются, элемент автоматически окажется в другом месте после следующей загрузки. Уникальный id дает детерминированный tie-breaker.
@OrderColumn
@OrderColumn хранит позицию элемента отдельным столбцом:
@OneToMany
@OrderColumn(name = "position")
private List<OrderItem> items;Порядок — часть состояния отношения. При вставке элемента в начало ORM может обновить position у многих строк.
Сравнение
| Свойство | @OrderBy | @OrderColumn |
|---|---|---|
| источник порядка | значения атрибутов | отдельная позиция |
| хранит ручной порядок | нет | да |
| изменение поля меняет место | да | нет, пока не изменена позиция |
| цена вставки в середину | обычная сортировка чтения | возможны массовые UPDATE |
Ловушки
- Опечатка в атрибуте строки
@OrderByпроявится при построении метаданных/запроса. - Порядок без уникального tie-breaker может быть нестабилен.
@OrderColumnтребует аккуратно работать с конкурентным редактированием списка.Setне выражает позиционный контракт; для порядка нужна подходящая коллекция.- Lazy-коллекция все равно требует открытого контекста загрузки или явного fetch.
Связано: Маппинг Hibernate, Fetch type Hibernate, Проблема N plus 1 Select Hibernate, Оператор ORDER BY.
Вопросы
Что хранит @OrderBy? Ничего дополнительного; задает сортировку при загрузке.
Что хранит @OrderColumn? Позицию элемента в отдельной колонке.
Почему вставка в начало с @OrderColumn дорогая? Нужно сдвинуть позиции следующих элементов.
Можно ли писать имя SQL-колонки в @OrderBy? По JPA используют имена persistent-атрибутов entity.