Interview replay

Full round replay — dirty checking

10 minintermediate115 yrs

Timed verbal replay with pass/fail criteria per follow-up.

How to run this

Answer out loud, timed. Do not read the entry first. Then compare against "The Answer" and "Interviewer's Next Move" and mark yourself.

The opener

What is dirty checking, and why did my entity save without a save() call?

Budget: 45 seconds. Going long here is itself a fail signal.

Follow-ups

  1. 1. “What is it comparing against?

    Testing: Snapshot, not the database.

    Scoring

    Pass: An in-memory snapshot the persistence context took when it loaded the entity — a copy of every persistent field. Not the database; it does not re-read anything to find out what changed.

    Fail: Says it queries the database to compare.

  2. 2. “When does the flush happen?

    Testing: The half people miss.

    Scoring

    Pass: At commit, and also before most queries, so a query sees pending changes. That means a read part-way through a method can trigger writes from earlier in it.

    Fail: Only says at commit.

  3. 3. “What does save() do on an already-managed entity?

    Testing: Whether they know it is redundant.

    Scoring

    Pass: Nothing — the entity was going to be written at flush anyway. There is an argument for keeping it as documentation that the method writes, but it changes no behaviour.

    Fail: Believes it is required.

  4. 4. “When does mutating an entity NOT write?

    Testing: The mirror case.

    Scoring

    Pass: When it is detached — returned from a service whose transaction ended, deserialised, or constructed — because there is no snapshot to compare against. And under readOnly = true, where the snapshot is never taken.

    Fail: Thinks setters always persist.

  5. 5. “What does dirty checking cost?

    Testing: Whether they see it as free.

    Scoring

    Pass: Two copies of everything loaded, since the context holds the entity and its snapshot. And a flush proportional to what has been loaded rather than to what changed — fifty thousand entities means comparing all of their fields to find one change.

    Fail: Assumes it is free.

  6. 6. “A read-only batch job runs out of memory. Why?

    Testing: Applying the cost.

    Scoring

    Pass: It accumulates. Every loaded entity plus its snapshot is retained until the transaction ends, so a job that walks a large table uses roughly twice the entities' footprint. flush() and clear() periodically, a StatelessSession, or readOnly to drop the snapshot half.

    Fail: Blames the result set size alone.

  7. 7. “Someone fixes that by flushing more often. Does it help?

    Testing: The wrong fix that sounds right.

    Scoring

    Pass: No. flush() writes pending changes and keeps every entity managed, so memory is unchanged and each flush re-compares everything loaded so far — it gets slower. clear() is what releases them.

    Fail: Accepts flush as the fix.

  8. 8. “What does readOnly = true actually change?

    Testing: Precision.

    Scoring

    Pass: Hibernate skips taking the snapshot, so there is no dirty checking and no flush. Real saving on memory and time, and any mutation in that method is then silently discarded with no error.

    Fail: Calls it just a hint or just documentation.

  9. 9. “Which columns does the UPDATE set?

    Testing: A detail with real consequences.

    Scoring

    Pass: All of them by default — one statement per entity type, built at startup and cached. That is why column-level audit triggers fire for columns that did not change. @DynamicUpdate builds it per flush from the changed fields.

    Fail: Assumes only the changed column.

  10. 10. “A method changes a field then returns early to avoid saving. Does it work?

    Testing: The most damaging misunderstanding.

    Scoring

    Pass: No. The entity is managed and mutated, so the transaction commits and the UPDATE is issued. Returning is not a rollback — validate before mutating, or throw so the transaction actually rolls back.

    Fail: Believes the early return prevents the write.

Score yourself

10/10 — you can explain the mechanism and predict every case from it 7-9 — solid; the flush-without-clear and early-return answers are where points go 4-6 — you know it exists but not what it costs; redo the Production tier 0-3 — issue an UPDATE without calling save yourself first

← Back to What is dirty checking, and why did my entity save without a save() call?