Optimal Lock and Hibernate Web Application

I have a web application created using Tapestry5 (java webframework) and Hibernate. Now I'm trying to add an optimistic lock. So I added a version attribute and optimistic locks, so it was easy and fast.

But since my web application works with the session-per-request pattern, I'm not sure which is the best way to use this optimistic lock.

What's happening:

UserA opens a page with a form that is loaded with values ​​from entityA (version 1).

UserB opens a page with a form that is loaded with values ​​from entityA (version 1).

UserA changes some values ​​and submits the form. -> A new request receives an entityA object (version 1) and commits the changes (entityA is now version 2)

UserB modifies some values ​​and submits the form. -> A new request receives an entityA object (version 2 ) and commits the changes (entityA is now version 3)

What is going to happen

UserB changes should not be made. But because of the session-per-request template, the time window in which an optimistic Hibernate lock error can occur is reduced to the time interval only from a new request after sending for commit, which is not the desired result.

Possible solutions

After some research, I found the following:

  • Add a hidden field to the entity version form

I could use this value to set the version of the object before committing, but the Hibernate documentation does not recommend setting this value. It also works only if the object is disconnected and reconnected, because otherwise the value set manually will be ignored using Hibernate.

Secondly, I can use this version value for manual verification if the version when the form was rendered is the same as the version of the object loaded in the submit request. Then, if necessary, throw an optimistic Exception.

  • Put a separate object in HttpSession, so I don’t need to upload it again in submit

Conclusion

These methods work, but do not seem to me very practical and are easily mistaken. Therefore, I wonder how other people implement this problem.

+4
source share
2 answers

As a result, I performed the following steps:

  • Add a hidden field to the entity version form
  • Using dto form objects
  • Attaching these dto objects to httpsession (dialog state for multiple requests)
  • Manual version checking between dto and the actual object
+1
source

When you disconnect a persistent object only to transfer it to the web layer, as an example, create a DTO to transfer objects to the web layer. in this case, we convert Entity objects to DTO objects using getters and setters.

If you need to maintain an optimistic locking concurrency control, you must save the version number in your application (this is different from manually setting the version number). Otherwise, we cannot indicate sleep mode, which was an old version of the loaded record. The hibernation documentation says: "Keep a disconnected session close to the save level. Use an EJB bean session to hold the session in a three-tier environment. Do not transfer it to the web layer or even serialize it to a separate layer to save it in HttpSession . ", but in all environments there is no session with EJB beans state in the business layer. In this case, we must maintain the version number.

While you can maintain the version, you do not need to manually check the version in the program, it is effective if you enable it to sleep because you cannot predict the depth of the hierarchy of objects.

So what you can do, you need to set the version back to a persistent entity if you use separate objects in the web layer. Then hibernate will take care of Cocurrency Control.

0
source

All Articles