Dirty checking is Hibernate’s automatic mechanism that tracks changes to persistent entities and ensures that any updates you make to those objects are automatically synchronized to the database when the session is flushed (usually at transaction commit).
🔹 How does it work?
- When you load or save an entity in a Hibernate
Session
, it becomes persistent and is stored in the first-level cache. - Hibernate takes a snapshot of the entity’s initial state when it’s first loaded or saved.
- If you modify the entity’s fields while it’s still attached to the session, Hibernate compares the current state to the snapshot during
flush()
. - If any differences (i.e., “dirtiness”) are detected, Hibernate generates the appropriate
UPDATE
SQL statement.
🔹 Example:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 1L); // loads entity, takes initial snapshot
user.setUsername("new_username"); // modifies persistent entity
// No explicit update needed!
// Hibernate detects the change at flush/commit:
tx.commit(); // generates UPDATE automatically
session.close();
✅ Without dirty checking, you’d have to manually issue an UPDATE
or save()
call — but with dirty checking, Hibernate does it for you.
🔹 Key points about dirty checking:
✅ It works only for persistent entities attached to an open session.
✅ Happens automatically when you call flush()
or commit()
.
✅ Saves developers from writing explicit UPDATE
statements → you just modify objects, and Hibernate persists changes.
✅ Dirty checking respects transactional boundaries, ensuring changes are atomic.
🔹 Limitations:
- If the entity is detached (e.g., session closed), changes won’t be tracked or persisted automatically.
- Using
StatelessSession
disables dirty checking entirely — you must manage updates manually.
✅ Key takeaway:
Dirty checking lets you focus on changing objects naturally in code, while Hibernate tracks and synchronizes those changes with the database automatically at flush time.