Careeroza
Flush and Commit
Flush Is Not Commit
| Flush | Commit | |
|---|---|---|
| What | Sends pending SQL (INSERT/UPDATE/DELETE) to the database | Makes the transaction's changes permanent |
| Undoable? | Yes, a rollback still undoes flushed SQL | No |
| Visible to other transactions? | No (with normal isolation) | Yes |
| Triggered by | em.flush(), before a JPQL query that might be affected, before commit | commit() / end of @Transactional method |
When Hibernate Flushes (FlushModeType.AUTO)
@Transactional
public void demo() {
Product p = em.find(Product.class, 1L);
p.setPrice(new BigDecimal("1299.00")); // nothing sent yet
// a query on products: Hibernate flushes first so the query sees the new price
List<Product> cheap = em.createQuery(
"select p from Product p where p.price < :max", Product.class)
.setParameter("max", new BigDecimal("1300.00"))
.getResultList();
System.out.println(cheap.size());
} // commit: flush (nothing left) + COMMITOrder of SQL
# logExample output
Hibernate: select p1_0.id,...,p1_0.stock from products p1_0 where p1_0.id=? Hibernate: update products set category=?,created_at=?,description=?,name=?,price=?,sku=?,status=?,stock=? where id=? Hibernate: select p1_0.id,...,p1_0.stock from products p1_0 where p1_0.price<?
Order of Operations at Flush
- INSERTs (in the order
persistwas called) - UPDATEs (dirty entities)
- Collection changes
- DELETEs
Note: Because of this order, deleting a row and inserting a new one with the same unique value in one transaction can fail with a constraint violation. Call em.flush() after the remove to force the DELETE first.
Exercise
Exercise: In this method, how many SQL statements run, and in what order? Product a = em.find(Product.class, 1L); Product b = em.find(Product.class, 1L); b.setStock(10); a.setStock(10); (row 1 had stock 120; transaction then commits).
Show answer
1. select ... from products where id=? (first find)
second find: no SQL - same object from the persistence context (a == b)
2. update products set ... where id=? (one UPDATE at commit;
a and b are the same object,
so it is dirty only once)