Gymterview
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.