Rox
Rox

Reputation: 2917

Entitymanager.flush() VS EntityManager.getTransaction().commit - What should I prefer?

What should I prefer when updating the database? What are the pros & cons with either method and when shall I use the one or the other?

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    employee.getPeriod().setEndDate(endDate);
    em.flush();
}

public void disemployEmployee(Integer employeeId, Date endDate) {
    Employee employee = (Employee)em.find("Employee", employeeId);
    em.getTransaction().begin();
    employee.getPeriod().setEndDate(endDate);
    em.getTransaction().commit();
}

Upvotes: 55

Views: 107643

Answers (5)

DataNucleus
DataNucleus

Reputation: 15577

According to the javadoc for flush and commit, flush is only for use within a transaction. It flushes (but doesn't commit), whereas commit commits data (obviously). They are distinct; there is no "preference" to be had.

The first example is wrong, and should result in an exception on calling flush (TransactionRequiredException).

Upvotes: 20

Nayan Wadekar
Nayan Wadekar

Reputation: 11602

In your first example, the changes to the data are reflected in database after encountering flush, but it is still in transaction.

But in second example, you are committing transaction immediately. Therefore the changes are made into the database & transaction also ends there.

Sometimes, flush may be useful to persist the data in between the ongoing transaction & then finally commit the changes afterwards. So you can also rollback the previous changes if there occurs some problem afterwards, like for batch insert/update.

Upvotes: 59

Mariam A. Moustafa
Mariam A. Moustafa

Reputation: 185

I think the missing part is, flush() just add to the datasources to be ready to commit, gives actual ids but not persist by default.

So if you need flush() to work as commit() you need to set the flush mode to Commit in the EntityManager by:

void setFlushMode(FlushModeType flushMode)
Set the flush mode that applies to all objects contained in the persistence context.

Note that FlushModeType is an enum that has these two values:

FlushModeType AUTO (Default) Flushing to occur at query execution. Since: JPA 1.0 FlushModeType COMMIT Flushing to occur at transaction commit. The provider may flush at other times, but is not required to. Since: JPA 1.0

I hope this help

Upvotes: 0

Dormouse
Dormouse

Reputation: 1637

I would go for container managed transaction whenever possible. Bean managed transactions usually require significantly more code, because of the Exception possibilities. Also, it's more error prone (rollbacks, resource management).

That said, I would use a flush after the commit in container managed mode. That way I can catch possible PersistenceExceptions in my storage module and convert it to some more meaningful Exception for my use case module. This because I don't want to handle storage-specific Exceptions here, because I might swap the storage module out for something that does not use JPA... which never happened to me :)

Upvotes: 0

Ahamed Mustafa M
Ahamed Mustafa M

Reputation: 3139

Both of your code samples doesn't persist or merge the entity state to be written to DB.

I don't think it appropriate to compare EntityManager.flush() and EnityManager.EntityTransaction.commit().

flush() MUST be enclosed in a transaction context and you don't have to do it explicitly unless needed (in rare cases), when EntityTransaction.commit() does that for you.

Refer this link Is it necessary to call a flush() (JPA interface) in this situation?

Refer this link Question about flushing with JPA before a query is called for a scenario to use flush()

Upvotes: 5

Related Questions