Reputation: 2922
I have an EJB where I am saving an object to the database. In an example I have seen, once this data is saved (EntityManager.persist) there is a call to EntityManager.flush(); Why do I need to do this? The object I am saving is not attached and not used later in the method. In fact, once saved the method returns and I would expect the resources to be released. (The example code does this on a remove call as well.)
if (somecondition) {
entityManager.persist(unAttachedEntity);
} else {
attachedEntityObject.setId(unAttachedEntity.getId());
}
entityManager.flush();
Upvotes: 82
Views: 195581
Reputation: 6226
A call to EntityManager.flush();
will force the data to be persisted in the database immediately as EntityManager.persist()
will not (depending on how the EntityManager is configured: FlushModeType (AUTO or COMMIT) by default is set to AUTO and a flush will be done automatically. But if it's set to COMMIT the persistence of the data to the underlying database will be delayed until the transaction is committed.
Upvotes: 72
Reputation: 48753
EntityManager.flush()
sends actual SQL commands to DB.
Persistence framework usually manages transactions behind the scene. So there is no guaranty that flushed queries will be successfully committed.
EntityManager.flush()
is always called just before the transaction commit by persistence framework automatically behind the scene.
EntityManager.persist()
only registers an entity to persistence context without sending any SQL statements to DB. That means you won't get auto generated IDs after persist()
. You just pass persisted object and eventually after later flush()
it gets ID. You can call flush()
yourself to get those IDs earlier. But again it is not the end of transaction so it can be rolled back and even more: changes might be seen (via phantom reads) by other transactions/thread/processes/servers and then disappear depending on DB engine and isolation level of current and foreign transaction!
Upvotes: 14
Reputation: 319
The EntityManager.flush()
operation can be used the write all changes to the database before the transaction is committed. By default JPA does not normally write changes to the database until the transaction is committed. This is normally desirable as it avoids database access, resources and locks until required. It also allows database writes to be ordered, and batched for optimal database access, and to maintain integrity constraints and avoid deadlocks. This means that when you call persist, merge, or remove the database DML INSERT
, UPDATE
, DELETE
is not executed, until commit, or until a flush is triggered.
Upvotes: 21
Reputation: 546
So when you call EntityManager.persist()
, it only makes the entity get managed by the EntityManager
and adds it (entity instance) to the Persistence Context
. An Explicit flush()
will make the entity now residing in the Persistence Context
to be moved to the database (using a SQL).
Without flush(), this (moving of entity from Persistence Context
to the database) will happen when the Transaction to which this Persistence Context
is associated is committed.
Upvotes: 23
Reputation: 3709
EntityManager.persist()
makes an entity persistent whereas EntityManager.flush()
actually runs the query on your database.
So, when you call EntityManager.flush()
, queries for inserting/updating/deleting associated entities are executed in the database. Any constraint failures (column width, data types, foreign key) will be known at this time.
The concrete behaviour depends on whether flush-mode is AUTO or COMMIT.
Upvotes: 27