I am trying to learn optimistic concurrency control.
The following program
- opens a session, creates a row in table : id=1 name = "raj", commits and closes the session
- start a thread, that sleeps initially for 3 sec. Then opens session2, updates the person having id =1 with name = "raj10". Then session2 is closed.
- In session3, i modify the same db row (with id=1). But the thing is that, this row is loaded before the thread in step 2 loads the same db row. And in session3 the loaded db row is updated (now this is stale because thread in step2 already modified it). So i catch the staleObjectStateException. Inside the catch block i load it again, update and then save it.
i get the following exception: Exception in thread "main" org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [com.raj.hibernate.optimistic.OptPerson#1]
Please tell me
- what i should have in my catch block to successfully update with new value.
would the session.merge help me here.
final SessionFactory factory = new Configuration().configure() .buildSessionFactory(); Session session = factory.openSession(); session.beginTransaction(); OptPerson optP1 = new OptPerson(); optP1.setName("raj"); session.save(optP1); session.getTransaction().commit(); session.close(); System.out.println("done saving, closed session"); new Thread() { public void run() { try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Session session2 = factory.openSession(); session2.beginTransaction(); OptPerson p1 = (OptPerson) session2.get(OptPerson.class, 1); p1.setName("raj10"); session2.save(p1); session2.getTransaction().commit(); session2.close(); System.out.println("modified person in session2"); } }.start(); Session session3 = factory.openSession(); session3.beginTransaction(); OptPerson p1 = (OptPerson) session3.get(OptPerson.class, 1); System.out.println("read person in session3"); Thread.sleep(8000); try { p1.setName("man"); session3.save(p1); session3.getTransaction().commit(); } catch (StaleObjectStateException ex) { System.out.println("inside catch block"); OptPerson p3 = (OptPerson) session3.get(OptPerson.class, 1); p3.setName("man"); session3.saveOrUpdate(p3); //OptPerson p4 = (OptPerson) session3.merge(p1); session3.getTransaction().commit(); } finally { session3.close(); }