Hibernate: flush() and commit()

JavaHibernateOrm

Java Problem Overview


Is it good practice to call org.hibernate.Session.flush() separately?

As said in org.hibernate.Session docs,

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

Could you explain the purpose of calling flush() explicitely if org.hibernate.Transaction.commit() will do it already?

Java Solutions


Solution 1 - Java

In the Hibernate Manual you can see this example

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();

Without the call to the flush method, your first-level cache would throw an OutOfMemoryException

Also you can look at this post about flushing

Solution 2 - Java

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. You can synchronize your database with small chunks of data using flush() instead of committing a large data at once using commit() and face the risk of getting an OutOfMemoryException.

commit() will make data stored in the database permanent. There is no way you can rollback your transaction once the commit() succeeds.

Solution 3 - Java

One common case for explicitly flushing is when you create a new persistent entity and you want it to have an artificial primary key generated and assigned to it, so that you can use it later on in the same transaction. In that case calling flush would result in your entity being given an id.

Another case is if there are a lot of things in the 1st-level cache and you'd like to clear it out periodically (in order to reduce the amount of memory used by the cache) but you still want to commit the whole thing together. This is the case that Aleksei's answer covers.

Solution 4 - Java

flush(); Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory. It will update or insert into your tables in the running transaction, but it may not commit those changes.

> You need to flush in batch processing otherwise it may give > OutOfMemoryException.

Commit(); Commit will make the database commit. When you have a persisted object and you change a value on it, it becomes dirty and hibernate needs to flush these changes to your persistence layer. So, you should commit but it also ends the unit of work (transaction.commit()).

Solution 5 - Java

It is usually not recommended to call flush explicitly unless it is necessary. Hibernate usually auto calls Flush at the end of the transaction and we should let it do it's work. Now, there are some cases where you might need to explicitly call flush where a second task depends upon the result of the first Persistence task, both being inside the same transaction.

For example, you might need to persist a new Entity and then use the Id of that Entity to do some other task inside the same transaction, on that case it's required to explicitly flush the entity first.

@Transactional
void someServiceMethod(Entity entity){
    em.persist(entity); 
    em.flush() //need to explicitly flush in order to use id in next statement
    doSomeThingElse(entity.getId());    
}

Also Note that, explicitly flushing does not cause a database commit, a database commit is done only at the end of a transaction, so if any Runtime error occurs after calling flush the changes would still Rollback.

Solution 6 - Java

By default flush mode is AUTO which means that: "The Session is sometimes flushed before query execution in order to ensure that queries never return stale state", but most of the time session is flushed when you commit your changes. Manual calling of the flush method is usefull when you use FlushMode=MANUAL or you want to do some kind of optimization. But I have never done this so I can't give you practical advice.

Solution 7 - Java

session.flush() is synchronise method means to insert data in to database sequentially.if we use this method data will not store in database but it will store in cache,if any exception will rise in middle we can handle it. But commit() it will store data in database,if we are storing more amount of data then ,there may be chance to get out Of Memory Exception,As like in JDBC program in Save point topic

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionbsiamionauView Question on Stackoverflow
Solution 1 - JavaAleksei BulgakView Answer on Stackoverflow
Solution 2 - JavaAnand KulkarniView Answer on Stackoverflow
Solution 3 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 4 - JavaAshuView Answer on Stackoverflow
Solution 5 - Javaadn.911View Answer on Stackoverflow
Solution 6 - JavadimasView Answer on Stackoverflow
Solution 7 - JavaGautam PrustyView Answer on Stackoverflow