I was gathering information about the flush() method, but I'm not quite clear when to use it and how to use it correctly. From what I read, my understanding is that the contents of the persistence context will be synchronized with the database, i. e. issuing outstanding statements or refreshing entity data.
Now I got following scenario with two entities A
and B
(in a one-to-one relationship, but not enforced or modelled by JPA). A
has a composite PK, which is manually set, and also has an auto-generated IDENTITY field recordId
. This recordId
should be written to entity B
as a foreign-key to A
. I'm saving A
and B
in a single transaction. The problem is that the auto-generated value A.recordId
is not available within the transaction, unless I make an explicit call of em.flush()
after calling em.persist()
on A
. (If I have an auto-generated IDENTITY PK then the value is directly updated in the entity, but that's not the case here.)
Can em.flush()
cause any harm when using it within a transaction?
Probably the exact details of em.flush()
are implementation-dependent.
In general anyway, JPA providers like Hibernate can cache the SQL instructions they are supposed to send to the database, often until you actually commit the transaction.
For example, you call em.persist()
, Hibernate remembers it has to make a database INSERT, but does not actually execute the instruction until you commit the transaction. Afaik, this is mainly done for performance reasons.
In some cases anyway you want the SQL instructions to be executed immediately; generally when you need the result of some side effects, like an autogenerated key, or a database trigger.
What em.flush()
does is to empty the internal SQL instructions cache, and execute it immediately to the database.
Bottom line: no harm is done, only you could have a (minor) performance hit since you are overriding the JPA provider decisions as regards the best timing to send SQL instructions to the database.