Reputation: 12610
For synchronization and to retrieve the DB-generated ID's I feel coerced to call EntityManager.flush()
at several places.
Performance implications aside, are there reasons not to call flush()
?
In other words, is there any observable difference for the caller of my (DAO, ...) method if it does/doesn't flush()
?
My scenario is in the context of a framework to support our JPA developers. I would provide some functionality which may or may not need to flush()
somewhere deep in the call hierarchy. Will the user of these functions have to know if/when flushing occurs, or is it a private implementation detail without noticable effect to the caller?
Upvotes: 5
Views: 8013
Reputation: 9102
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.
Upvotes: 4
Reputation: 21145
Performance pretty much sums up most of the reasons "not" to call flush. Flush is is a way to force all change statements to be pushed to the database immediately, rather than accumulate and be sent as a larger batch. It can be useful, as some transactions can be quite large and need to be cleared to release the memory, as well as to force a certain order for your updates to go into the database.
Other than performance and provider specific issues, the only other reason not to call flush is application specific, such as when some changes might violate a database constraint and require further modifications later on.
Upvotes: 4