org.hibernate.OptimisticLockException Solution

(68 Views)


In this article, we are discussing the hibernate org.hibernate.OptimisticLockException

Description

By J2EE and Jboss.org Standards this Exception is Thrown by the persistence provider when an optimistic locking conflict occurs. This exception may be thrown as part of an API call, a flush or at commit time. The current transaction, if one is active, will be marked for rollback.

org.hibernate.OptimisticLockException is very common exception. When you use optimistic locking and detects a differrent update of an entity, then Hibernate throws it. That most often happens for these reasons:

  1. Two differrent users try to make changes or update the same entity at the same point of time.
  2. One user performs 2 updates of the same entity, and you didn't refresh the entity representation in the client side and the version value was not updated after the first change or update.

Here is an example code snippet with 2 concurrent updates.

// EntityManager and transaction 1 EntityManager em1 = emf.createEntityManager(); em1.getTransaction().begin(); // EntityManager and transaction 2 EntityManager em2 = emf.createEntityManager(); em2.getTransaction().begin(); // update 1 Employee emp1 = em1.find(Employee.class, 1L); emp1.setFirstName("changed"); // update 2 Employee emp2 = em2.find(Employee.class, 1L); emp2.setFirstName("changed"); // commit transaction 1 em1.getTransaction().commit(); em1.close(); // commit transaction 2 try { em2.getTransaction().commit(); Assert.fail(); } catch (RollbackException e) { Assert.assertTrue(e.getCause() instanceof OptimisticLockException); log.info("2nd transaction failed with an OptimisticLockException"); } em2.close();

Cause Of Exception

As you can see, I use two independent EntityManagers and start a transaction with both of them, get the Employee entity with id 1 and update the first name attribute. This works fine until I try to commit the second transaction and Hibernate checks for concurrent changes or updates of Employee entity. In a real world application, this would, of course, be done by 2 concurrent calls of the same method.

Solution

You can't do much to avoid this exception without introducing pessimistic locking which would downgrade the performance of application. Just try to update the entity representations in the client as often as possible and to keep the update or change operations as low as possible. That should avoid OptimisticLockExceptions, and you'll need to handle the rest of them in the client application. But if only one user is causing the OptimisticLockException on its own, you can find the bug and you can easily fix it. If you use hibernate optimistic locking, Hibernate uses a version to keep record of the current version of the entity and to prevent concurrent modifications. You, therefore, need to make sure that your client always updates its representation version of the entity after the user make any change on the entity. And your client application should not cache the entity or any value object representing it.

Solution Worked 0 UpvotesUpvote

        

Solution Didn't Worked 0 DownvotesDownvote



Comments



Search