Вопрос-ответ

How to choose the id generation strategy when using JPA and Hibernate

Как выбрать стратегию генерации идентификаторов при использовании JPA и гибернации

Я просматривал раздел генерации идентификаторов справочного руководства по гибернации и "сохранение java с помощью гибернации"

В сочетании Hibernate и JPA доступно довольно много опций.

Я искал дополнительную документацию о том, как выбрать конкретную стратегию генерации идентификаторов.

Я также ищу переломные моменты.

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

Я хочу получить информацию о компромиссах.

Есть ли какая-либо доступная литература?

Переведено автоматически
Ответ 1

В документе API об этом очень ясно сказано.


Все генераторы реализуют интерфейс org.hibernate.id.IdentifierGenerator. Это очень простой интерфейс. Некоторые приложения могут предоставлять свои собственные специализированные реализации, однако Hibernate предоставляет ряд встроенных реализаций. Сокращенные имена встроенных генераторов следующие:


увеличение


генерирует идентификаторы типа long, short или int, которые уникальны только тогда, когда ни один другой процесс не вставляет данные в ту же таблицу. Не использовать в кластере.


идентификация


поддерживает столбцы идентификаторов в DB2, MySQL, MS SQL Server, Sybase и HypersonicSQL. Возвращаемый идентификатор имеет тип long, short или int.


последовательность


использует последовательность в DB2, PostgreSQL, Oracle, SAP DB, McKoi или генератор в Interbase. Возвращаемый идентификатор имеет тип long, short или int


hilo


использует алгоритм hi / lo для эффективной генерации идентификаторов типа long, short или int, учитывая таблицу и столбец (по умолчанию hibernate_unique_key и next_hi соответственно) в качестве источника значений hi. Алгоритм hi/ lo генерирует идентификаторы, уникальные только для определенной базы данных.


продолжение


использует алгоритм hi / lo для эффективной генерации идентификаторов типа long, short или int с учетом именованной последовательности базы данных.


uuid


использует 128-битный алгоритм UUID для генерации идентификаторов типа string, уникальных в сети (используется IP-адрес). UUID кодируется в виде строки длиной 32 шестнадцатеричных цифры.


guid


использует строку GUID, сгенерированную базой данных на MS SQL Server и MySQL.


native


выбирает идентификатор, последовательность или hilo в зависимости от возможностей базовой базы данных.


назначено


позволяет приложению присваивать идентификатор объекту перед вызовом функции save() . Это стратегия по умолчанию, если элемент не указан.


выберите


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


иностранный


использует идентификатор другого связанного объекта. Обычно он используется в сочетании с ассоциацией первичного ключа.


последовательность-идентификация


специализированная стратегия генерации последовательности, которая использует последовательность базы данных для фактической генерации значения, но сочетает это с JDBC3 getGeneratedKeys для возврата сгенерированного значения идентификатора как части выполнения инструкции insert. Эта стратегия поддерживается только в драйверах Oracle 10g, предназначенных для JDK 1.4. Комментарии к этим операторам insert отключены из-за ошибки в драйверах Oracle.


Если вы создаете простое приложение с небольшим количеством одновременных пользователей, вы можете использовать increment, identity, hilo и т.д.. Они просты в настройке и не требуют большого кодирования внутри базы данных.

Вы должны выбрать последовательность или guid в зависимости от вашей базы данных. Они безопасны и лучше, потому что id генерация будет происходить внутри базы данных.

Обновление: Недавно у нас возникла проблема с idendity, где вместо primitive type (int) это было исправлено с помощью warapper type (Integer).

Ответ 2

В принципе, у вас есть два основных варианта:


  • Вы можете сгенерировать идентификатор самостоятельно, в этом случае вы можете использовать назначенный идентификатор.

  • Вы можете использовать @GeneratedValue аннотацию, и Hibernate назначит идентификатор для вас.

Для сгенерированных идентификаторов у вас есть два варианта:


  • Идентификаторы UUID.

  • Числовые идентификаторы.

Для числовых идентификаторов у вас есть три варианта:

IDENTITY это хороший выбор только тогда, когда вы не можете использовать SEQUENCE (например, MySQL), потому что он отключает пакетные обновления JDBC.

SEQUENCE является предпочтительным вариантом, особенно при использовании с оптимизатором идентификаторов, таким как pooled или pooled-lo.

TABLE следует избегать, поскольку для извлечения идентификатора и блокировок на уровне строк используется отдельная транзакция, которая плохо масштабируется.

Ответ 3


Некоторое время назад я написал подробную статью о генераторах ключей гибернации: http://blog.eyallupu.com/2011/01/hibernatejpa-identity-generators.html

Выбор правильного генератора - сложная задача, но важно попытаться сделать это правильно как можно скорее - поздняя миграция может стать кошмаром.

Немного не по теме, но хороший шанс поднять вопрос, который обычно упускается из виду, а именно обмен ключами между приложениями (через API). Лично я всегда предпочитаю суррогатные ключи, и если мне нужно передать свои объекты другим системам, я не предоставляю свой ключ (даже если он суррогатный) – я использую дополнительный ‘внешний ключ’. В качестве консультанта я не раз видел "отличные" системные интеграции с использованием объектных ключей (подход "это есть, давайте просто воспользуемся этим") только для того, чтобы год или два спустя обнаружить, что у одной из сторон возникли проблемы с диапазоном ключей или что-то в этом роде, требующее глубокой миграции в системе, раскрывающей ее внутренние ключи. Раскрытие вашего ключа означает, что фундаментальный аспект вашего кода подвергается внешним ограничениям, которым на самом деле не следует подвергаться.

Ответ 4

Я нахожу эту лекцию очень ценной https://vimeo.com/190275665 в пункте 3 обобщены эти генераторы, а также дан некоторый анализ производительности и первое руководство при использовании каждого из них.

java hibernate jpa