AUTO flush may synchronize pending changes before a query, while COMMIT defers some work; neither mode is a commit or an isolation policy.
JPA flush mode: know when pending writes become SQL
The surprise SELECT
A service changes a managed receipt, then runs a JPQL query against the same table. Under the usual AUTO mode, the provider may flush pending DML first so the query sees a consistent view of managed changes. That adds SQL earlier than the caller expected and can expose constraint violations at the query line. Flush versus commit matters here: synchronized SQL remains rollbackable until the transaction commits.
Do not use COMMIT as a correctness shortcut
COMMIT mode can defer synchronization, but visibility of pending changes to queries is not a portable substitute for explicit command ordering. If a workflow requires a database constraint or generated value before the next step, flush intentionally and handle the failure at that boundary. If it requires an atomic outcome, keep the whole command in one transaction. Bulk JPQL writes can leave managed objects stale regardless of mode; clear or refresh before trusting those instances.
Observe provider behavior
Log SQL in an integration test, not in production customer traffic. Change a row, execute an overlapping query, then compare SQL order and results under the actual provider and dialect. Repeat with a native query if the application uses one. Count flushes and statements under a representative batch path because an unexpected flush inside a loop can defeat JDBC batching.
Implementation contract
@Transactional
public boolean reserveReceipt(UUID receiptId) {
ReceiptEntity receipt = entityManager.find(ReceiptEntity.class, receiptId);
receipt.markReserved();
entityManager.flush(); // force constraint checks here; commit still follows
return receiptRepository.existsById(receiptId);
}Cost and verification
An explicit flush adds a database synchronization point and can fragment batches. AUTO may flush before overlapping queries; COMMIT may delay work, but neither lowers the amount of required DML.
Common Mistakes
- Do not confuse flush with a durable commit.
- Do not assume COMMIT makes pending changes visible to every query.
- Do not rely on SQL execution order without a provider-backed integration test.
Read next
Spring Data JPA saveAndFlush is a SQL boundary, not a commit, Spring Data JPA bulk update: the managed entity can still hold the old value, JPA insert batching: bound both JDBC trips and persistence-context memory, Spring JPA entity lifecycle: managed changes and detached objects, Spring TransactionTemplate: roll back a failed multi-row change.
