Scenario: inside one transaction, load an order, mutate a managed item's quantity field directly (no repository.save() call), then run an unrelated query (customerRepository.count()) in the same transaction. 1. select o1_0.id,c1_0.id,c1_0.name,i1_0.order_id,i1_0.id,i1_0.quantity,i1_0.sku,o1_0.version from jpa_order o1_0 left join jpa_customer c1_0 on c1_0.id=o1_0.customer_id left join jpa_order_item i1_0 on o1_0.id=i1_0.order_id where o1_0.id=? 2. select count(*) from jpa_customer c1_0 3. update jpa_order_item set order_id=?,quantity=?,sku=? where id=? total statements: 3 An UPDATE for jpa_order_item appears BEFORE the transaction ever commits and without save() ever being called, because Hibernate's dirty checking flushes pending changes ahead of any query that could otherwise see stale data. This is correct behaviour, but it means "no save() call" does not mean "no write" — see docs/02-the-jpa-side.md for the case where this surprises people (an outer @Transactional method that throws after this point still writes the row before the eventual rollback un-writes it).