Hibernate: лучший тип коллекции для использования - сумка, сумка, набор, список, карта

Я ищу то, что большинство людей используют в качестве своего типа коллекции при создании ассоциаций "один ко многим" в Hibernate. Унаследованное приложение, которое я поддерживаю, использует пакеты исключительно, но сохраняет их как списки в коде. Связанные таблицы имеют поле id, поэтому идентификатор кажется более подходящим, но документация рекомендует Set.

EDIT: Я ошибочно напомнил, что документация рекомендует набор. В действительности официальная документация одинаково расплывчата по всем типам сборов. Я нахожу, что некоторые веб-сайты, похоже, делают вывод, что Set является наиболее распространенным, а книга Hibernate, которую я читаю, прямо говорит об этом:

Это наиболее распространенная постоянная коллекция в типичном приложении Hibernate. (см. стр. 242 "Сохранение Java с гибернацией" Кристианом Бауэром и Гевином Кингом)

Я думаю, это то, что меня бросило, и заставил меня искать то, что используют другие.

EDIT2: обратите внимание, что Гевин Кинг является создателем Hibernate

Ответ 1

Хорошо, через некоторое время я нашел причину НЕ использовать набор как тип коллекции. Из-за проблем с переопределением hashcode/equals и тем, как сохраняется спящий режим, использование любой функции java API, которая вызывает hashcode/equals, является плохой идеей. Нет никакого хорошего способа последовательно сравнивать объекты до и после сохранения. Придерживайтесь коллекций, которые не полагаются на equals/hashcode, например bag.

Подробнее здесь:

http://community.jboss.org/wiki/EqualsandHashCode (эта ссылка заставляет это звучать как бизнес-ключ, это путь, но прочитать следующую ссылку полностью, чтобы понять, почему это не всегда хорошая идея)

https://forum.hibernate.org/viewtopic.php?f=1&t=928172 (прочитайте всю дискуссию, чтобы закружить голову)

Ответ 2

Основываясь на опыте использования обоих, я бы рекомендовал использовать List. Если вы получаете данные из базы данных и отображаете/управляете ими, ее почти всегда нужно поддерживать в последовательном порядке. Вы можете использовать SortedSet, но это может добавить целый мир боли (переопределение равных, hashcode и т.д. И сортировка по-разному) по сравнению с просто добавлением порядка и сохранением его в списке. Списки легче манипулировать - если пользователь удаляет строку 3 на странице, просто удалите элемент 3 в списке. Работа с набором, по-видимому, связана с большим количеством ненужного кода и беспорядочным взаимодействием с итераторами.

Когда я использовал Sets with Hibernate, я часто обнаруживал, что я разорвал все Sets через несколько недель и заменил списки, потому что Sets давали мне слишком много ограничений.

Документация Hibernate и сторонние инструменты, по-видимому, используют Sets по умолчанию, но из-за трудного опыта я нашел гораздо более продуктивным использование списков.

Ответ 3

Я предполагаю, что люди используют всевозможные вещи:-) - разные типы коллекций служат для разных целей, поэтому "лучший" зависит от того, что вам нужно.

Тем не менее, использование List в коде обычно более удобно, чем использование Set, хотя указанный List неупорядочен. Если ничего больше, ".get(0)" легче на глазах, чем .iterator().next():-) Поддержка сумки Hibernate определенно подходит для этой цели, плюс вы даже можете добавить декларацию order-by (если применимо) и иметь свой список отсортирован.

idbag - это совершенно другое животное, используемое для ассоциаций "многие-ко-многим"; вы не можете сравнить его с обычным Set или List.

Ответ 4

Я бы рекомендовал использовать набор, потому что набор определяется как набор уникальных элементов, и обычно это то, с чем вы имеете дело.

И .iterator().next() сохраняется, когда в вашей коллекции нет элемента.

.get(0) может вызывать IndexOutOfBoundsException, если вы открываете пустой список.