0
votes

I have a question related to optimistic locking in Spring/Hibernate actually.

I have following scenario with typical REST application with SQL database.

  1. User A enters page and reads data - version 0 of entity - GET request
  2. User B enters page and reads data - version 0 of entity - GET request
  3. User A saves data - version 1 of entity - PUT request
  4. User B wants to save data (PUT request), but I should see optimistic lock exception

Now my question: Where hibernate saves data about entity version? I understand the situation when everything is in the same transaction:

  1. Load data
  2. Someone changed entity in the different transaction
  3. Save data

But in my situation version will vanish GET and PUT are in totally different transaction/threads etc.

In my opinion I should save somewhere version loaded by the user to have correlation between GET and PUT requests e.g. in HTTP session or just return version in the response and then send that version in the PUT request.

Can it be done in the better way? Like out of the box?

1

1 Answers

0
votes

JPA/Hibernate have @Version column in entity definition to check optimistic or pessimistic lockings. JPA/Hibernate saves versions in the table. For example you have Country table in db:

CREATE TABLE country (
  id BIGINT NOT NULL AUTO_INCREMENT,
  version BIGINT DEFAULT 0,
  ...
);

And Country entity:

@Entity
@Table(name = "country")
public class Country implements Serializable {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id", nullable = false)
  private Long id;

  @Version
  @Column(name = "version")
  private Long version;

  ...
}

If you update the country entity instances with optimistic lock conflicts, you get OptimisticLockException in JPA. You don't need to manage the versions, JPA/Hibernate checks the versions of entity instances for you.

Update for different transactions:

In different transactions you can get OptimisticLockException too because JPA/Hibernate checks in every update the version columns with database table. As long as you save your changes (commit), another changes of entity versions will be checked, doesn't matter whether in the same transaction or different transaction. Better you can manage your transactions with @Transactional annotation in Spring framework.