Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about Hibernate session.flush()

I want to inquire about what actually the flush method does in the following case:

for (int i = 0; i < myList.size(); i++) {     Car c = new Car( car.get(i).getId(),car.get(i).getName() );     getCurrentSession().save(c);     if (i % 20 == 0)         getCurrentSession().flush(); } 

Does this means that after the iteration 20, the cache is flushed, and then the 20 held memory objects are actually saved in the database ?

Can someone please explain to me what will happen when the condition is true.

like image 367
Mahmoud Saleh Avatar asked Jul 18 '10 09:07

Mahmoud Saleh


People also ask

What is the use of session flush in Hibernate?

Flushing the session forces Hibernate to synchronize the in-memory state of the Session with the database (i.e. to write changes to the database). By default, Hibernate will flush changes automatically for you: before some query executions. when a transaction is committed.

Does session flush commit transaction?

flush() will synchronize your database with the current state of object/objects held in the memory but it does not commit the transaction. So, if you get any exception after flush() is called, then the transaction will be rolled back.

What is the default flush mode in Hibernate?

AUTO. The Session is sometimes flushed before query execution in order to ensure that queries never return stale state. This is the default flush mode.

Can session be reused in Hibernate?

So, how can i reuse an Hibernate Session, in the same thread, that has been previously closed? Either use the built-in " managed " strategy (set the current_session_context_class property to managed ) or use a custom CurrentSessionContext derived from ThreadLocalSessionContext and override ThreadLocalSessionContet.


1 Answers

From the javadoc of Session#flush:

Force this session to flush. Must be called at the end of a unit of work, before committing the transaction and closing the session (depending on flush-mode, Transaction.commit() calls this method).

Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.

In other words, flush tells Hibernate to execute the SQL statements needed to synchronize the JDBC connection's state with the state of objects held in the session-level cache. And the condition if (i % 20 == 0) will make it happen for every i multiple of 20.

But, still, the new Car instances will be held in the session-level cache and, for big myList.size(), you're going to eat all memory and ultimately get an OutOfMemoryException. To avoid this situation, the pattern described in the documentation is to flush AND clear the session at regular intervals (same size as the JDBC batch size) to persist the changes and then detach the instances so that they can be garbage collected:

13.1. Batch inserts

When making new objects persistent flush() and then clear() the session regularly in order to control the size of the first-level cache.

Session session = sessionFactory.openSession(); Transaction tx = session.beginTransaction();  for ( int i=0; i<100000; i++ ) {     Customer customer = new Customer(.....);     session.save(customer);     if ( i % 20 == 0 ) { //20, same as the JDBC batch size         //flush a batch of inserts and release memory:         session.flush();         session.clear();     } }  tx.commit(); session.close(); 

The documentation mentions in the same chapter how to set the JDBC batch size.

See also

  • 10.10. Flushing the Session
  • Chapter 13. Batch processing
like image 60
Pascal Thivent Avatar answered Sep 22 '22 18:09

Pascal Thivent