middle
Стратегии генерации идентификаторов
Стратегия генерации ID определяет, как будет назначаться первичный ключ новой сущности.
Основные стратегии JPA
| Стратегия | Механизм | Batch insert | Рекомендация |
|---|---|---|---|
| IDENTITY | Автоинкремент БД | Не поддерживает | MySQL (простые случаи) |
| SEQUENCE | Sequence в БД | Поддерживает | PostgreSQL, Oracle |
| TABLE | Таблица-счётчик | Поддерживает | Не рекомендуется (медленно) |
| AUTO | Hibernate выбирает | Зависит от выбора | Не для продакшена |
| UUID | UUID-генерация | Поддерживает | Распределённые системы |
Примеры каждой стратегии
// 1. IDENTITY — автоинкремент на стороне БД
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// БД генерирует ID при INSERT
// Не поддерживает batch insert — Hibernate выполняет INSERT немедленно для получения ID
// 2. SEQUENCE — последовательность в БД (рекомендуемая)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
@SequenceGenerator(name = "user_seq", sequenceName = "user_sequence",
allocationSize = 50)
private Long id;
// Hibernate заранее запрашивает блок ID из sequence (allocationSize)
// Поддерживает batch insert — ID известен до выполнения INSERT
// 3. TABLE — отдельная таблица для хранения счётчиков
@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "user_gen")
@TableGenerator(name = "user_gen", table = "id_generator",
pkColumnName = "gen_key", valueColumnName = "gen_value",
allocationSize = 50)
private Long id;
// Переносима между БД, но самая медленная — требует блокировки строки
// 4. AUTO — Hibernate сам выбирает
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
// В Hibernate 6 по умолчанию выбирает SEQUENCE (если БД поддерживает) или TABLE
// 5. UUID
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
// Подходит для распределённых систем (не зависит от БД)
// Занимает 16 байт вместо 8 (Long), хуже индексируется в B-Tree
Важное
- SEQUENCE — рекомендуемая стратегия для PostgreSQL/Oracle (поддерживает batch insert)
- IDENTITY — проще, но блокирует batch insert (Hibernate выполняет INSERT сразу для получения ID)
allocationSizeу SEQUENCE — Hibernate запрашивает блок ID одним запросом, снижая обращения к БД- UUID — для распределённых систем, где централизованная генерация ID невозможна
Частые ошибки
- IDENTITY + batch insert — batch insert невозможен с IDENTITY; если нужны пакетные вставки — SEQUENCE
allocationSize=1у SEQUENCE — Hibernate будет вызыватьnextvalна каждый INSERT; увеличьте до 50- Несовпадение
allocationSizeи INCREMENT в БД — allocationSize в аннотации и INCREMENT BY в DDL sequence должны совпадать - AUTO в Hibernate 6 — по умолчанию выбирает TABLE (не SEQUENCE!) для некоторых БД, что медленнее
Как используется в 2026
- SEQUENCE с
allocationSize=50— стандарт для PostgreSQL-приложений - UUID v7 (time-ordered) — набирает популярность для распределённых систем (лучше индексируется чем UUID v4)
- Hibernate 6.x:
@UuidGenerator(style = TIME)— генерация time-based UUID - TSID (Time-Sorted ID) — альтернатива UUID, компактнее (Long), используется в некоторых проектах
На собеседовании: интервьюер ожидает сравнение IDENTITY vs SEQUENCE. Главный аргумент за SEQUENCE — поддержка batch insert. Упомяните allocationSize и объясните, почему значение по умолчанию (50) лучше 1. Если спросят про распределённые системы — UUID v7.