Ответ
Dirty Checking — это механизм Hibernate для автоматического обнаружения изменений в persistent-сущностях и генерации соответствующих SQL-запросов UPDATE при синхронизации состояния сессии с БД (flush).
Как работает:
- При загрузке сущности Hibernate сохраняет её «исходное» состояние в кеше первого уровня (snapshot).
- Перед выполнением flush Hibernate сравнивает текущее состояние каждого управляемого объекта (attached) с его snapshot.
- Если поля отличаются, сущность помечается как «грязная» (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()для каждого изменения, снижая вероятность ошибок.