136

When we are updating a record, we can use session.flush() with Hibernate. What's the need for flush()?

9 Answers 9

172

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

Allowing to explicitly flush the Session gives finer control that may be required in some circumstances (to get an ID assigned, to control the size of the Session,...).

2
  • 11
    Note that this answer describes the DEFAULT Hibernate behavior: the flush behavior can be changed via the Flush Mode setting. Details are in docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/… (version 3.5).
    – SteveT
    Commented Oct 11, 2012 at 14:27
  • 1
    I found the document where it's said exactly what you are saying but I have question that what will be the priority means suppose 1) I have class where I am saving object using code id = session.save(obj); and transaction is committed at very next line but obj is not getting saved to DB ,Why? 2) I saved obj using session.save(obj); with commit and while returning I used return obj.getprimaryID(); In this case obj is saved to DB. So why this behavior is happening ?
    – Amogh
    Commented Jul 23, 2015 at 19:57
100

As rightly said in above answers, by calling flush() we force hibernate to execute the SQL commands on Database. But do understand that changes are not "committed" yet. So after doing flush and before doing commit, if you access DB directly (say from SQL prompt) and check the modified rows, you will NOT see the changes.

This is same as opening 2 SQL command sessions. And changes done in 1 session are not visible to others until committed.

4
  • 16
    Well - the changes can be slightly visible. For example, an uncommitted row can create a lock on the inserted but uncommitted row and delay the same row from being inserted by another session until the transaction is committed or rolled-back. So it is not completely invisible.
    – rghome
    Commented Mar 31, 2015 at 11:43
  • 5
    I've surfed all over the web and this is the answer that's finally made me get it. Thanks.
    – Siddhartha
    Commented Oct 5, 2016 at 1:26
  • what is the use of putting .flush() in a for loop then if commit() does a flush at the end?
    – Heetola
    Commented Jan 8, 2020 at 8:31
  • @Kaushik Lele Whats the point of flush() if the data is not visible after flush? Can you elaborate on some of the finer use cases where this comes in handy?
    – java_geek
    Commented May 11, 2020 at 11:03
35

I only know that when we call session.flush() our statements are execute in database but not committed.

Suppose we don't call flush() method on session object and if we call commit method it will internally do the work of executing statements on the database and then committing.

commit=flush+commit (in case of functionality)

Thus, I conclude that when we call method flush() on Session object, then it doesn't get commit but hits the database and executes the query and gets rollback too.

In order to commit we use commit() on Transaction object.

1
  • 1
    Can you give some details on whats the need for flush?
    – java_geek
    Commented May 11, 2020 at 11:06
16

Flushing the Session gets the data that is currently in the session synchronized with what is in the database.

More on the Hibernate website:

flush() is useful, because there are absolutely no guarantees about when the Session executes the JDBC calls, only the order in which they are executed - except you use flush().

2
  • Can you provide a scenario when user should worry about the sequence? Use of hibernate is to make DB related things transparent to user. When we do "commit", flushing happens automatically. What is the scenario where you will do flush but not commit? Commented Apr 3, 2015 at 5:09
  • 1
    @KaushikLele you can refer to this question stackoverflow.com/questions/37382872/…
    – Sam YC
    Commented May 23, 2016 at 10:07
13

You might use flush to force validation constraints to be realised and detected in a known place rather than when the transaction is committed. It may be that commit gets called implicitly by some framework logic, through declarative logic, the container, or by a template. In this case, any exception thrown may be difficult to catch and handle (it could be too high in the code).

For example, if you save() a new EmailAddress object, which has a unique constraint on the address, you won't get an error until you commit.

Calling flush() forces the row to be inserted, throwing an Exception if there is a duplicate.

However, you will have to roll back the session after the exception.

1
  • Only issue is hibernate will still fail to find the flushed item upon a search, at least using hibernate criteria queries. Not great.
    – mjs
    Commented Feb 26, 2023 at 11:03
8

The flush() method causes Hibernate to flush the session. You can configure Hibernate to use flushing mode for the session by using setFlushMode() method. To get the flush mode for the current session, you can use getFlushMode() method. To check, whether session is dirty, you can use isDirty() method. By default, Hibernate manages flushing of the sessions.

As stated in the documentation:

https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/flushing/Flushing.html

Flushing

Flushing is the process of synchronizing the state of the persistence context with the underlying database. The EntityManager and the Hibernate Session expose a set of methods, through which the application developer can change the persistent state of an entity.

The persistence context acts as a transactional write-behind cache, queuing any entity state change. Like any write-behind cache, changes are first applied in-memory and synchronized with the database during flush time. The flush operation takes every entity state change and translates it to an INSERT, UPDATE or DELETE statement.

The flushing strategy is given by the flushMode of the current running Hibernate Session. Although JPA defines only two flushing strategies (AUTO and COMMIT), Hibernate has a much broader spectrum of flush types:

  • ALWAYS: Flushes the Session before every query;
  • AUTO: This is the default mode and it flushes the Session only if necessary;
  • COMMIT: The Session tries to delay the flush until the current Transaction is committed, although it might flush prematurely too;
  • MANUAL: The Session flushing is delegated to the application, which must call Session.flush() explicitly in order to apply the persistence context changes.

By default, Hibernate uses the AUTO flush mode which triggers a flush in the following circumstances:

  • prior to committing a Transaction;
  • prior to executing a JPQL/HQL query that overlaps with the queued entity actions;
  • before executing any native SQL query that has no registered synchronization.
7

I would just like to club all the answers given above and also relate Flush() method with Session.save() so as to give more importance

Hibernate save() can be used to save entity to database. We can invoke this method outside a transaction, that’s why I don’t like this method to save data. If we use this without transaction and we have cascading between entities, then only the primary entity gets saved unless we flush the session.

flush(): Forces the session to flush. It is used to synchronize session data with database.

When you call session.flush(), the statements are executed in database but it will not committed. If you don’t call session.flush() and if you call session.commit() , internally commit() method executes the statement and commits.

So commit()= flush+commit. So session.flush() just executes the statements in database (but not commits) and statements are NOT IN MEMORY anymore. It just forces the session to flush.

Few important points:

We should avoid save outside transaction boundary, otherwise mapped entities will not be saved causing data inconsistency. It’s very normal to forget flushing the session because it doesn’t throw any exception or warnings. By default, Hibernate will flush changes automatically for you: before some query executions when a transaction is committed Allowing to explicitly flush the Session gives finer control that may be required in some circumstances (to get an ID assigned, to control the size of the Session)

3

Calling EntityManager#flush does have side-effects. It is conveniently used for entity types with generated ID values (sequence values): such an ID is available only upon synchronization with underlying persistence layer. If this ID is required before the current transaction ends (for logging purposes for instance), flushing the session is required.

1

With this method you evoke the flush process. This process synchronizes the state of your database with state of your session by detecting state changes and executing the respective SQL statements.

Not the answer you're looking for? Browse other questions tagged or ask your own question.