Что такое Dirty Checking в Hibernate?

«Что такое Dirty Checking в Hibernate?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Dirty Checking — это механизм Hibernate для автоматического обнаружения изменений в persistent-сущностях и генерации соответствующих SQL-запросов UPDATE при синхронизации состояния сессии с БД (flush).

Как работает:

  1. При загрузке сущности Hibernate сохраняет её «исходное» состояние в кеше первого уровня (snapshot).
  2. Перед выполнением flush Hibernate сравнивает текущее состояние каждого управляемого объекта (attached) с его snapshot.
  3. Если поля отличаются, сущность помечается как «грязная» (dirty), и для нее планируется UPDATE.

Пример:

// Сущность загружается в контексте сессии (attached state)
User user = session.get(User.class, 1L); // SELECT * FROM user WHERE id=1
// Hibernate запоминает snapshot (например, name='OldName')

user.setName("NewName"); // Изменение в памяти

transaction.commit(); // Или session.flush()
// Hibernate сравнивает: текущее name='NewName' vs snapshot name='OldName'
// Обнаружено изменение -> генерируется: UPDATE user SET name='NewName' WHERE id=1

Важные аспекты:

  • Работает только для сущностей в состоянии managed (attached) в рамках одной сессии.
  • @DynamicUpdate оптимизирует запрос, обновляя только измененные столбцы.
  • Почему это удобно: Избавляет разработчика от необходимости явно вызывать session.update() для каждого изменения, снижая вероятность ошибок.