Як вибрати стратегію генерації ідентифікаторів при використанні JPA та Hibernate


102

Я переглядав розділ покоління Id в довідковому посібнику зі спячки та "наполегливість Java зі сплячим режимом"

Існує досить багато варіантів, у поєднанні зі сплячим режимом та JPA.

Я шукав додаткову документацію щодо вибору конкретної стратегії генерації ідентифікаторів.

Я також шукаю переломні моменти.

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

Я хочу бути освіченим про компроміси.

Чи є в наявності література?

Відповіді:


92

Документ API дуже ясно в цьому.

Всі генератори реалізують інтерфейс org.hibernate.id.IdentifierGenerator. Це дуже простий інтерфейс. Деякі програми можуть вибрати власні спеціалізовані реалізації, однак, Hibernate пропонує ряд вбудованих реалізацій. Короткі назви вбудованих генераторів такі:

приріст

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

особистість

підтримує стовпці ідентичності в DB2, MySQL, MS SQL Server, Sybase та HypersonicSQL. Повертається ідентифікатор типу довгий, короткий або int.

послідовність

використовує послідовність у DB2, PostgreSQL, Oracle, SAP DB, McKoi або генератор в Interbase. Повертається ідентифікатор типу довгий, короткий або int

хіло

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

seqhilo

використовує алгоритм hi / lo для ефективного генерування ідентифікаторів типу long, short або int із заданою послідовністю баз даних.

uuid

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

орієнтир

використовує базу даних, що генерується на базі даних GUID, на MS SQL Server та MySQL.

рідний

вибирає ідентичність, послідовність або hilo залежно від можливостей базової бази даних.

призначений

дозволяє додатку призначити ідентифікатор об'єкту до виклику save (). Це стратегія за замовчуванням, якщо жоден елемент не вказаний.

виберіть

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

іноземні

використовує ідентифікатор іншого асоційованого об’єкта. Зазвичай він використовується в поєднанні з асоціацією первинного ключа.

послідовність-ідентичність

спеціалізована стратегія генерації послідовностей, яка використовує послідовність бази даних для фактичного генерування значення, але поєднує це з JDBC3 getGeneratedKeys для повернення згенерованого значення ідентифікатора як частини виконання оператора вставки. Ця стратегія підтримується лише на драйверах Oracle 10g, орієнтованих на JDK 1.4. Коментарі до цих операторів вставки вимкнено через помилку в драйверах Oracle.

Якщо ви будуєте просту програму з не надто одночасними користувачами, ви можете піти на приріст, особистість, hilo тощо. Це прості налаштування та не потрібно багато кодування всередині db.

Ви повинні вибрати послідовність або настанови залежно від вашої бази даних. Вони безпечні та кращі, оскільки idгенерація відбуватиметься всередині бази даних.

Оновлення: Нещодавно у нас виникла проблема з ідеальністю, де примітивний тип (int) це було виправлено, використовуючи замість цього тип warapper (Integer).


Дуже дякую за вашу відповідь. Я вже переглянув документи. Проте я шукаю, чому люди вживали б щось на кшталт хіло та секхіло. Коли ми робимо такий вибір. Які є випадки використання для вибору.

Коли є щось таке просте, як послідовність чи настанови, те, що може вимагати від розробника вибрати інші шляхи.

1
Я оновив свою відповідь. Насправді приріст, особистість, хіло тощо. Простіші. але вони не підходять для корпоративних програм. Зберегти всі варіанти - це не проблема, але переконайтеся, що ви використовуєте найкращий для вас варіант!
ManuPK

Так. Поки що я не мав привілею проголосувати або прийняти.

Я розглядаю дайвінг більш детально, якщо у вас є час, повідомте мене.

45

В основному у вас є два основні варіанти:

  • Ви можете генерувати ідентифікатор самостійно, і в цьому випадку ви можете використовувати призначений ідентифікатор .
  • Ви можете використовувати @GeneratedValueпримітку, і Hibernate призначить вам ідентифікатор.

Для створених ідентифікаторів у вас є два варіанти:

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

  • ІДЕНТИЧНІСТЬ
  • ПОСЛІДОВІСТЬ
  • ТАБЛИЦЯ

Ідентичність - це лише хороший вибір, коли ви не можете використовувати SEQUENCE (наприклад, MySQL), оскільки він вимикає пакетні оновлення JDBC .

SEQUENCE є кращим варіантом, особливо при використанні з оптимізатором ідентифікаторів, таким як об'єднаний або об'єднаний-lo .

ТАБЛИЦІ слід уникати будь-якою ціною, оскільки вона використовує окрему транзакцію для отримання ідентифікатора та блокувань рівня рядків, які погано масштабуються.


20


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

Вибір правильного генератора є складним завданням, але важливо спробувати якнайшвидше його виправити - пізня міграція може бути кошмаром.

Трохи поза темою, але хороший шанс підняти точку, як правило, ігнорують, а саме - це обмін ключами між програмами (через API). Особисто я завжди віддаю перевагу сурогатним ключам, і якщо мені потрібно зв’язати свої об’єкти з іншими системами, я не виставляю свій ключ (навіть якщо це сурогатний ключ) - я використовую додатковий "зовнішній ключ". Як консультант я не раз бачив «чудові» системні інтеграції за допомогою об’єктних ключів (підхід «це там, давайте просто скористаємося цим»), щоб лише через рік-два виявити, що одна сторона має проблеми з діапазоном ключів або чимось із вид, що вимагає глибокої міграції в системі, що відкриває свої внутрішні ключі. Розкривати свій ключ означає відкриття основного аспекту коду зовнішнім обмеженням насправді не слід піддаватися впливу.


2

Я вважаю цю лекцію дуже цінною https://vimeo.com/190275665 , у пункті 3 вона узагальнює ці генератори, а також дає аналіз ефективності та настанови під час використання кожного з них.


6
Це відео виглядає дуже знайомо.
Влад Міхалча
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.