Питання 13 · Розділ 16

Як працює механізм flush в Hibernate

Flush — процес синхронізації даних з persistence context (кеш Hibernate) в базу даних. Розуміння механізму flush критично важливе для управління транзакціями та оптимізації прод...

Мовні версії: English Russian Ukrainian

Огляд

Flush — процес синхронізації даних з persistence context (кеш Hibernate) в базу даних. Розуміння механізму flush критично важливе для управління транзакціями та оптимізації продуктивності.


🟢 Junior Level

Що таке flush

Flush — це процес запису всіх змін з пам’яті (persistence context) в базу даних.

User user = entityManager.find(User.class, 1L);
user.setName("New Name");  // змінено в пам'яті

// Flush ще не відбувся — БД НЕ оновлена!

entityManager.flush();  // явний flush — UPDATE виконано в БД
// або
// При commit — автоматичний flush

Коли відбувається flush

  1. При commit транзакції — автоматично
  2. При entityManager.flush() — явно
  3. Перед виконанням запиту — щоб повернути актуальні дані

🟡 Middle Level

FlushMode

// AUTO (за замовчуванням) — flush при необхідності
entityManager.setFlushMode(FlushModeType.AUTO);

// COMMIT — flush тільки при commit
entityManager.setFlushMode(FlushModeType.COMMIT);

// ALWAYS — перед кожним запитом (рідко використовується)
// (Примітка: FlushModeType.ALWAYS застарів в Hibernate 5 і видалений в Hibernate 6)

Ручний flush для batch-операцій

@Transactional
public void batchUpdate(List<User> users) {
    for (int i = 0; i < users.size(); i++) {
        entityManager.merge(users.get(i));

        if (i % 50 == 0) {
            entityManager.flush();  // скинути 50 UPDATE в БД
            entityManager.clear();  // очистити persistence context
        }
    }
    // Фінальний flush для решти
    entityManager.flush();
    entityManager.clear();
}

🔴 Senior Level

Внутрішня реалізація

Процес flush:

1. Dirty checking
   - Обхід всіх entities в persistence context
   - Порівняння snapshot з поточним станом
   - Для змінених — schedule UPDATE

2. Generation order
   - INSERT спочатку (щоб отримати ID)
   - UPDATE потім
   - DELETE в кінці (щоб уникнути FK violations)

3. SQL generation та Execution

Порядок операцій

При flush Hibernate дотримується порядку:

1. Всі entity INSERT (в порядку persist())
2. Всі entity UPDATE (в порядку dirty detection)
3. Всі collection UPDATE
4. Всі collection DELETE
5. Всі entity DELETE (в порядку remove())

Це важливо для:
- Foreign key constraints
- Referential integrity
- Identity generation

Просунуті налаштування

spring:
  jpa:
    properties:
      hibernate:
        order_inserts: true       # групування INSERT
        order_updates: true       # групування UPDATE
        jdbc.batch_size: 50

Best Practices

✅ AUTO flush mode за замовчуванням
✅ Ручний flush для batch-операцій
✅ flush + clear кожні 50-100 entities
✅ COMMIT mode коли не потрібні актуальні дані
✅ order_inserts/order_updates для оптимізації

❌ ALWAYS mode (уникайте)
❌ Flush без причини
❌ Без clear після flush в батчах

🎯 Шпаргалка для співбесіди

Обов’язково знати:

  • Flush — синхронізація даних з persistence context в БД
  • Відбувається при: commit, entityManager.flush(), перед запитом (AUTO mode)
  • FlushMode: AUTO (за замовчуванням), COMMIT (тільки при commit)
  • Порядок операцій: INSERT → UPDATE → DELETE (для FK constraints)
  • Для batch: flush + clear кожні 50-100 entities

Пов’язані теми:

  • [[12. Що таке dirty checking в Hibernate]]
  • [[7. Опишіть життєвий цикл Entity в Hibernate]]
  • [[14. У чому різниця між persist() і merge()]]
  • [[17. Як реалізувати оптимістичне блокування в JPA]]