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
, если вы открываете пустой список.