JPA EntityManager operations order

I have run into interesting issue recently. I use in the project JPA + Hibernate + EJB. The issue concerns saving and deleting entities in the same transaction. Database table which is used has an unique constraint defined on two columns.

What I have done was removing entity calling

entityManager.remove();

then the new entity has been added with the same values in two properties associated with columns used in the unique constraint but different values in other properties using:

entityManager.persist();

Those two operations have been carried out in a single transaction and have been executed in the order as presented above. Removal first, addition second.
What turned out, the operations on the database were executed in the inverted order and unique constraint got violated. It looked like the new entity was added before removing the previous one.

Apparently, looking at JPA specification, it does not force implementations to execute operations on the database in the order they were added to the transaction.

To deal with the situation as above, JPA provides

entityManager.flush();

method. Its responsibility is to synchronize persistence context to the underlying database.
So to avoid unique constraint violation you need to call flush() method after remove() method.

What is more, there is no risk that if the transaction is rolled back after calling flush() the entity will be removed anyway.  flush() force the persistence context to be synchronized to the database, but the transaction is still not committed, except it is committed  manually. If EJB layer is configured by default and JTA is used, then the transaction will be committed only after the methods returns from the EJB layer.

Leave a Reply

Your email address will not be published. Required fields are marked *