Reputation: 18639
I'm just experimenting with Optimistic locking.
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'm fetching one of the students and try to update its properties concurrently.
Thread t1 = new Thread(new MyRunnable(id));
Thread t2 = new Thread(new MyRunnable(id));
t1.start();
t2.start();
and inside of 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 is happening that first transaction updates object successfully and 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 ok.
My question is: 1) What should I do if I want second transaction to do nothing and not throw any exception.
2) What should I do if I want second transaction to override data updated by first transaction.
Thanks.
Upvotes: 8
Views: 29882
Reputation: 11
I had the same exception. It was solved once I changed
@GeneratedValue(strategy = GenerationType.SEQUENCE)
to
@GeneratedValue(strategy = GenerationType.AUTO)
in my entity.
My app runs on MySQL server.
Upvotes: -2
Reputation: 10750
I give a try to answer your questions:
You use optimistic locking. So you want that an OptimisticLockException
is thrown on version conflict - but you can catch it and do nothing. You can't switch it off for a second (whatever that means) transaction because you don't know if a version conflict will occur (this is the essence of the optimistic lock strategy: the optimistic assumption is that a version conflict won't occur very often)
If an OptimisticLockException
occurs, you basically have 2 options:
The problem is how or who is to decide which state is the actual "correct" (means latest) one if you have concurrent updates. As long as consistency is guaranteed, I wouldn't care.
Upvotes: 14
Reputation: 10762
Disclaimer: this is a suggestion; I haven't tried it myself.
I'd give up the version field entirely, and set this entity optimistic locking strategy to "none" in XML mapping:
<class name="Student" optimistic-lock="none"/>
or as an annotation:
@Entity(optimisticLock=OptimisticLockType.NONE)
These are Hibernate specific, you won't find them in JPA specification.
Upvotes: 0