Optimistic lock and org.hibernate.StaleObjectStateException:

I am just experimenting with optimistic blocking.

I have the following class:

@Entity public class Student { private Integer id; private String firstName; private String lastName; private Integer version; @Version public Integer getVersion() { return version; } //all other getters ommited. } 

Now I get one of the students and try to update its properties at the same time.

 Thread t1 = new Thread(new MyRunnable(id)); Thread t2 = new Thread(new MyRunnable(id)); t1.start(); t2.start(); 

and inside MyRunnable:

 public class MyRunnable implements Runnable { private Integer id; @Override public void run() { Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Student student = (Student) session.load(Student.class, id); student.setFirstName("xxxx"); session.save(student); session.getTransaction().commit(); System.out.println("Done"); } public MyRunnable(Integer id){ this.id = id; } } 

what happens when the first transaction update object succeeds and the second transaction throws:

 org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.vanilla.entity.Student#1] 

This is normal.

My question is: 1) What should I do if I want the second transaction to do nothing and not cause any exceptions.

2) What should I do if I want the second transaction to overlap the data updated by the first transaction.

Thanks.

+6
source share
3 answers

I will try to answer your questions:

  • You are using optimistic locking. This way you want OptimisticLockException be thrown into version conflict, but you can catch it and do nothing. You cannot disconnect it in the second (no matter what it means) transaction, because you do not know whether a version conflict will occur (this is the essence of an optimistic blocking strategy: the optimistic assumption is that a version conflict will not occur very often)

  • If an OptimisticLockException exists, you have basically 2 options:

    • discard changes (and possibly update the current state)
    • update only the version of your object (entities) and try to commit again

    The problem is how or who should decide which state is the actual β€œcorrect” (meaning the latter) if you have concurrent updates. As long as the consistency is guaranteed, I don't care.

+7
source

Disclaimer: this offer; I have not tried it myself.

I would completely abandon the version field and set this optimistic locking strategy for "none" in the XML mapping:

 <class name="Student" optimistic-lock="none"/> 

or as an abstract:

 @Entity(optimisticLock=OptimisticLockType.NONE) 

This is Hibernate specific, you will not find them in the JPA specification.

0
source

I had the same exception. It was resolved after I changed

 @GeneratedValue(strategy = GenerationType.SEQUENCE) 

to

 @GeneratedValue(strategy = GenerationType.AUTO) 

in my essence.

My application runs on a MySQL server.

0
source

Source: https://habr.com/ru/post/898689/


All Articles