Java – optimistic locking and org hibernate. StaleObjectStateException:
I'm just trying to be optimistic
I have the following courses:
@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'm catching one of the students and trying 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 myrunnable internal:
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; } }
The first transaction successfully updates the object 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]
that's OK.
My question is: 1) what should I do if I want the second transaction to do nothing and throw no exceptions?
2) What should I do if I want the second transaction to overwrite the data updated by the first transaction?
thank you.
Solution
I try to answer your question:
>You use optimistic locking Therefore, you want to throw an optimisticlockexception in case of a version conflict – but you can catch it and do nothing You can't turn it off for one second (no matter what it means) because you don't know whether there will be version conflicts (this is the essence of optimistic locking strategy: optimistic assumption is that version conflicts will not occur frequently) > if optimizationlockexception occurs, you basically have two options:
>Discard changes (perhaps refresh the current status) > refresh the version of your entity (entity) and try to commit again
If you have concurrent updates, the problem is how or who will decide which state is actually "correct" (indicating the latest) As long as consistency is guaranteed, I don't care