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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With