A call to flush()
synchorizes the persistence context with the database. This is primarily required - if there needs to be a query hit (via JPQL etc).
Later in the call stack to the database, and if the persistence context contains a dirty value for any of the objects whose state could possibly be affected by query results, then those needs to be synchronized. In fact the default FlushModeType
for JPA queries is AUTO
When queries are executed within a transaction, if FlushModeType.AUTO
is set on the Query or TypedQuery object, or if the flush mode setting
for the persistence context is AUTO (the default) and a flush mode
setting has not been specified for the Query or TypedQuery object, the
persistence provider is responsible for ensuring that all updates to
the state of all entities in the persistence context which could
potentially affect the result of the query are visible to the
processing of the query. The persistence provider implementation may
achieve this by flushing those entities to the database or by some
other means.
So as long as you are querying the object via its state and not JPA queries and the results of those queries are not dependent on the dirty state, then it's bad for performance calling flush as it involves repeated dirty state check instead of just at commit time.
@Adams mentioned about his experience with OpenJPA where flush breaks few things, so I guess different implementations have problems here.