Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HibernateOptimisticLockingFailureException while updating an object

Tags:

hibernate

I am getting following exception while updating an object.

HibernateOptimisticLockingFailureException: Object of class [User] with identifier [25614]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [User#25614]

Situation :- Reason why i am facing this error is that I have a form where users are displayed and I have two buttons there one for updating the password and one for editing the detail of the users. when I click on updating the password then it just query the object and updates its password and keep the object in hibernate session. And then I click on edit button and modify the information and then save it then it gives upper mentioned exception because the object, that I am trying to save, is not hibernate session object but an object with same identifier was queried by hibernate while updating the password. Now I have two objects with same identifier one is in hibernate session and another is not persisted (not detached object) yet. I want to update save the changes from not persisted object into the database but because there is an object with same identifier is in hibernate session so hibernate gives an exception.

How I can merge changes from not persisted objects to persisted one?

like image 521
Mukesh Kumar Avatar asked Sep 26 '11 13:09

Mukesh Kumar


1 Answers

The answer is in the question: when changing the password in the first transaction, the version field of the user entity is updated, but you keep an obsolete version of your user object in the HTTP session and try to update the user with this obsolete version in a second transaction.

Just make sure to refresh the user object you keep in the HTTP session each time the password is changed.

You might also manually copy each property of the modified user to the attached user object, but then you wouldn't benefit from optimistic locking anymore.

// first transaction:
User refreshedUser = userService.updateUserPassword(userId, newPassword);
request.getSession().setAttribute("user", refreshedUser);

// ...
// second transaction:
User modifiedUser = (User) request.getSession().getAttribute("user");
modifiedUser = userService.updateUser(modifiedUser);
request.getSession().setAttribute("user", modifiedUser);
like image 76
JB Nizet Avatar answered Oct 01 '22 14:10

JB Nizet