Подтвердить что ты не робот

Спящий режим: @OrderBy vs @OrderColumn для поддержания порядка сбора

Каков предпочтительный способ поддержания порядка коллекции при сохранении, а также при извлечении из базы данных?

Я знаю, что @OrderBy больше относится к сортировке в памяти, которая может работать при извлечении только тогда, когда вы задаете строки в порядке расположения столбца, который вы выбрали.

Предположим, что я решил использовать столбец, поддерживаемый последовательностью базы данных, будет спящий режим, чтобы элементы в коллекции сохранялись в том же порядке, что и в коллекции (например, List).

Любая мысль?

Подробнее:

Допустим, у меня есть класс A, который имеет отношения "один ко многим" с классом B. В поле первичного ключа "Id", который поддерживается последовательностью в БД.

Class A {
  List<B> bList;
}

Я всегда хотел сохранить порядок элементов B в A, как показано ниже:

bList = { b1, b2, b3 }

Один из способов достижения - использовать @OrderBy ( "Id ASC" ). Это будет работать только тогда, когда список B сохраняется в следующем порядке:

----------------
Id ----bValue
----------------

1------ b1
2------ b2
3-------b3
------------------

Когда мы извлекаем, так как он упорядочен по Id, порядок поддерживается.

Предположим, что коллекция B сохраняется следующим образом:

----------------
Id ----bValue
----------------
1------ b2
2------ b1
3-------b3
------------------

Когда мы извлекаем, порядок списка B идет для броска (поскольку это порядок по столбцу Идентификатор). Поэтому мой вопрос, если коллекция B всегда сохраняется в том же порядке, что и в списке, или нет.

4b9b3361

Ответ 1

OrderBy добавляет предложение order by к сгенерированному SQL для упорядочения членов извлеченной коллекции по столбцу таблицы целевого объекта:

@OrderBy("lastname ASC")
public List<Student> students;

будет генерировать SQL-запрос, например

select ... order by student.lastname ASC

OrderColumn определяет имя дополнительного столбца в таблице, содержащего индекс объекта в списке. Если вы измените порядок элементов в списке, Hibernate изменит значение этого столбца. И если ваши ученики имеют 0, 3 и 5 в качестве значений в этом столбце, список будет

[student0, null, null, student3, null, student5]

Это хорошо описано в javadoc этих двух аннотаций.

EDIT:

Порядок, в котором назначены B-идентификаторы, зависит от того, как вы сохраняете эти экземпляры B:

  • если вы явно вызываете session.save(), из session.saveOrUpdate(), это присваивает идентификатор сущности, поэтому вызов его для b1, b2 и b3 будет уважать порядок
  • AFAIK, все остальные методы (cascading, merge(), persist()) не гарантируют никакого порядка (кроме случаев, когда вы сливаетесь или сохраняетесь, а затем flush())

Итак, если вы хотите, чтобы список держал b1, b2 и b3 в этом порядке, независимо от того, как они сохраняются, лучше всего добавить в коллекцию аннотацию @OrderColumn. Hibernate автоматически заполнит этот столбец 0 для b1, 1 для b2 и 2 для b3. И когда вы перезагрузите родительский объект, они будут в том же порядке в списке.