2

I konw that What em.flush() does is to empty the internal SQL instructions cache, and execute it immediately to the database. Correct use of flush() in JPA/Hibernate

but when I used JPA em.flush() to excute sql into database ,I found sql couldnot be executed immediately to the database. I couldnot find the data in the database before current trasaction was commited.

example in play framwork:

em=JPA.em();
Transaction tx=em.getTransaction();
tx.begin();  
em.persist(customer);  
em.flush();  
em.persist(address);  
tx.commit(); 

I set a breakpoint at line em.flush(),when I steped over the em.flush();
then ,i couldnot find the costomer data in the database.

if I omit the em.flush(); Data would also into database when the current trasaction was commited.So,what use of the em.flush() ?

Community
  • 1
  • 1
Glowd
  • 31
  • 4

1 Answers1

0

Entity manager flush operation sends the sql to the database, but remember that when a transaction is in process, the data send to database through sql is persisted only when the database is told to commit.

This is general database behaviour during transaction and you use transaction to set a boundary for database operations to be atomic.

Even when using plain jdbc instead of any orm you will see this behaviour unless of course when the auto commit is enabled for each of the sql query sent. Under the hood, the orm also uses jdbc. So for a single resource transaction (e.g., a single database), the usual idiom is to first set the autoCommit false on the jdbc connection, then send multiple inserts/updates through SQL and then call commit on the connection. If some exception was reported then call rollback. So the data is persisted only when the final call to commit is sent to database.

UPDATE

You need to understand that flush() without an active transaction is not going to work. Also there is a thing called FlushMode which actually controls when the flush is going to happen You can have a look at the answer here. The key to understanding all this is that data sent to database in the form of insert/updates do not immediately make it persistent unless the transaction is committed but the same transaction has access to the changed data (changed but yet not persisted).On the database side you can visualize this as a seperate area for each transaction where each transaction can change the data within itself but the data that finally goes into the underlying table does so only after the transaction is told to commit. The flush is also implicitly called by the provider before running a query whose results may be affected by the state of persistent context. For e.g., if you load an entity, then change its property and then run a query for that entity, then provider sees that the change must first be sent to database in its transaction and then the entity is queried so that the loaded properties reflect the changed one. However the changed data will not be persisted to the actual table row until the transaction is committed.

Community
  • 1
  • 1
Shailendra
  • 8,874
  • 2
  • 28
  • 37
  • Thank you ,I got it.But if I omit the em.flush(); Data would also into database when the current trasaction was commited.So,How to use the em.flush() for me. – Glowd Oct 13 '13 at 15:58
  • Hello,please give me some advice,I think that I understand how to use flush().persist() means that data is holded by JPA,while the data wouldnot into database until flush() is excuted. so I have a test, System.out.println("Customercount :"+Customer.count());//0 manager.persist(custemer); System.out.println("Customer count :"+Customer.count());//1 so I think the console result should be 0,0 ,other than 0,1 – Glowd Oct 15 '13 at 02:48