Card 04/ 07

GotchaDifficulty: Advanced1 min

A Modified Detached Entity Changes Nothing

emp is detached, then its name field is changed directly, then the transaction flushes. Nothing happens — not an error, not a write, nothing.

java
Employee emp = em.find(Employee.class, id);
em.detach(emp);
emp.name = "changed-after-detach";
em.flush();
text
flushed after modifying detached entity (should NOT throw, and should NOT persist the change)
re-read from a fresh call, name = Alex (should still be Alex, not changed-after-detach)
run in a container — the database was never touched

Dirty checking — the mechanism jdbc-vs-jpa covered, where JPA notices a change with no explicit save() — only watches managed entities. detach() turns that watching off for this one object, and setting emp.name afterward is exactly as inert as setting a field on any plain Java object. The field genuinely changed, in memory, on that one reference — the database never heard about it.

merge() is the way back in — not by re-enabling tracking on the same object, but by copying its state onto a new, managed instance and handing that back. The original reference stays detached and stale forever; only the object merge() returns is worth continuing to use.