简体   繁体   中英

How to correctly use optimisstic locking, catch StaleObjectState exceptions with Spring and Hibernate

I'm trying to use Hibernate for the first time. I have a need to make use of optimistic locking, so that the first commit wins. I worked out how to do that by way of hibernate managed version numbers in a test project. The test project uses just Hibernate, no Spring, so the code for working with the database goes something like this:

get session from sessionfactory
open transaction
perform database actions
commit transaction with error handling

My understanding is that I can make use of Spring to get transaction management and reduce the code to something like this:

perform database actions

What I do not know:

  1. How to set up Spring at all. I'd like to use XML over annotations. Just a link to a good reference would be awesome.
  2. How does the error handling come in with the Spring implementation? Where would I catch the StaleObjectStateException ?
  3. What is the best design structure? I've seen a DAO singleton that all threads use to interact with the database, and that seemed reasonable to me.

Basically you just add a version field to your entities, you should also have an id.

In your code you need to manage this version, ie the code calling your persistence layer has to first get the object with its correct version number before changing the entity.

Hibernate takes care of update of the version field. So you just need to have it at the last value it was set. When updating the entity, hibernate will increment the field so you don't need to create a sequence as you would do for the id.

The client code needs to manage the staleObjectStateException. When this exception occurs, it means the object was changed by other code or you did not get the latest version. You may decide on what to do then: get a fresher version and make the change, indicate to the user that someone else did a change if there is a UI...

You may also create a base class for your entities to always have the id and version fields. Note that the version number is useful if it is a read-write entity.

Finally you want to annotate the version field with @javax.persistence.Version

Actually it's a JPA concept also:

    private int version;

    public AbstractReadWriteEntity() {}

    @javax.persistence.Version
    @javax.persistence.Column(name = "VERSION")
    public int getVersion()...

Also to understand what it does at db level: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html#transactions-optimistic

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM