-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 
Author Message
 Post subject: StaleObjectStateException
PostPosted: Tue Jul 11, 2006 10:13 am 
Beginner
Beginner

Joined: Fri Mar 04, 2005 7:12 pm
Posts: 34
I have written an object called Patient and a simple PatienDAO object to handle creation and updating and querying the Patient objects. Recently setup a GUI so that the objects can be edited from multiple locations in the application, and encountered StaleObjectStateException, and wrote the following tests to try to understand this problem better.

First test runs successfully. The object patient was instantiated in the setup, so the DAO adds the patient to the database via createPatient, a query is then done, and then I alter the first name to Sammy, update the object, alter the last name to Revised, and update the object:

Code:
   public void testMultipleDAOUpdates2(){
      assertTrue(patientDAO.createPatient(patient));
      List<Patient> patients = patientDAO.getAllPatients();

      patient.setFirstName("Sammy");
      assertTrue(patientDAO.updatePatientValues(patient));
      patient.setLastName("Revised");
      assertTrue(patientDAO.updatePatientValues(patient));
   }


The following code also runs fine, adding a for loop and updating patient:

Code:
   public void testPatientUpdates4(){
         patientDAO.createPatient(patient);
         List<Patient> patients = patientDAO.getAllPatients();
         
         for (Patient p : patients) {
            p.setGender("Female");
            p.setWeight(25.95);
            assertTrue(patientDAO.updatePatientValues(p));
         }
         
         patients = patientDAO.getAllPatients();   
      }


However, the following code yields a StaleObjectStateException at the indicated line. The only difference between this test and the previous one is that I have combined the updates from the two tests:

Code:
   public void testPatientUpdates3(){
      patientDAO.createPatient(patient);
      List<Patient> patients = patientDAO.getAllPatients();
      
      for (Patient p : patients) {
         p.setGender("Female");
         p.setWeight(25.95);
         assertTrue(patientDAO.updatePatientValues(p));
      }

      patient.setFirstName("Sammy");
      patientDAO.updatePatientValues(patient); // EXCEPTION HERE!
      patient.setLastName("Revised");
      patientDAO.updatePatientValues(patient);   
   }




The failure trace is:
Code:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [edu.utah.cdmcc.entities.Patient#1]
   at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1680)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2271)
   at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2180)
   at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2456)
   at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:91)
   at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
   at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:140)
   at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
   at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
   at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:988)
   at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:337)
   at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
   at edu.utah.cdmcc.entities.PatientDAO.updatePatientValues(PatientDAO.java:198)
   at database.tests.TestPatientAdditionValidationDeletion.testPatientUpdates3(TestPatientAdditionValidationDeletion.java:264)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:585)
   at junit.framework.TestCase.runTest(TestCase.java:154)
   at junit.framework.TestCase.runBare(TestCase.java:127)
   at junit.framework.TestResult$1.protect(TestResult.java:106)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.framework.TestResult.run(TestResult.java:109)
   at junit.framework.TestCase.run(TestCase.java:118)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at junit.framework.TestSuite.runTest(TestSuite.java:208)
   at junit.framework.TestSuite.run(TestSuite.java:203)
   at junit.extensions.TestDecorator.basicRun(TestDecorator.java:22)
   at junit.extensions.TestSetup$1.protect(TestSetup.java:19)
   at junit.framework.TestResult.runProtected(TestResult.java:124)
   at junit.extensions.TestSetup.run(TestSetup.java:23)
   at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
   at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
   at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


The "supporting code" for these tests is in my DAO, consisting of createPatient, updatePatientValues, and getAllPatients; these are shown below for readers' reference:

Code:
   public boolean createPatient(Patient newPatient) {
      if(trialDBNumberAlreadyExists(newPatient.getTrialDbCode())) return false;
      personValidator = new ClassValidator<Patient>(Patient.class);
      validationMessages = personValidator.getInvalidValues(newPatient);
      if (validationMessages.length == 0) {
         session = HibernateUtil.getSessionFactory().getCurrentSession();
         session.beginTransaction();
         session.save(newPatient);
         session.getTransaction().commit();
         return true;
      } else
         return false;
   }

   public boolean updatePatientValues(Patient patient) {
      personValidator = new ClassValidator<Patient>(Patient.class);
      validationMessages = personValidator.getInvalidValues(patient);
      if (validationMessages.length == 0) {
         session = HibernateUtil.getSessionFactory().getCurrentSession();
         session.beginTransaction();
         session.saveOrUpdate(patient);
         session.getTransaction().commit();
         return true;
      } else
         return false;
   }

   @SuppressWarnings("unchecked")
   public List<Patient> getAllPatients(){
      session = HibernateUtil.getSessionFactory().getCurrentSession();
      session.beginTransaction();
      List<Patient> results =  session.getNamedQuery(Patient.GETALLPATIENTS).list();
      session.getTransaction().commit();
      return results;
   }


Using 3.1.0beta5 tools with Eclipse 3.2 final.

I have been looking at this code too long to see what is probably obvious! I appreciate any help in understanding this problem. Thanks.

- Mike Dean

_________________
J. Michael Dean, MD


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 1:46 am 
Newbie

Joined: Thu Feb 01, 2007 6:44 am
Posts: 4
Location: India
Hi,
Did u solve the problem ? Am curious as am getting a similar problem


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 6:52 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
public void testPatientUpdates3(){
patientDAO.createPatient(patient);
List<Patient> patients = patientDAO.getAllPatients();

for (Patient p : patients) {
p.setGender("Female");
p.setWeight(25.95);
assertTrue(patientDAO.updatePatientValues(p));
}

patient.setFirstName("Sammy");
patientDAO.updatePatientValues(patient); // EXCEPTION HERE!
patient.setLastName("Revised");
patientDAO.updatePatientValues(patient);
}


you have reference patient and second reference is p.you are updating values by patientDAO.updatePatientValues(p) then this refernece has version lets say 1 and again you are updateing value of same row by patientDAO.updatePatientValues(patient); with earliar reference patient which has version 0 .so this will definitely give you this Exception.Always use same reference in Junit to create and update value

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 7:22 am 
Newbie

Joined: Thu Feb 01, 2007 6:44 am
Posts: 4
Location: India
Thanks Dharamendra for chipping in.

Actually my case is much simpler

The code is something like below (where the same reference is being used)

---------------------------------------------------
//Code
task.setTaskName("TestTask");
taskDao.save(task);
tast.setTaskName("Updated Task");
taskDao.update(task);
---------------------------------------------------

The exception message is as below.
----------------------------------------------------
Could not synchronize database state with session Class: org.hibernate.event.def.AbstractFlushingEventListener Method: performExecutions
=== Exception ===
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect):
---------------------------------------------------

Appreciate the help.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 05, 2007 8:31 am 
Expert
Expert

Joined: Tue Jan 30, 2007 12:45 am
Posts: 283
Location: India
hi sony_thomas

send taskDao code .will give more clarity for dig out

_________________
Dharmendra Pandey


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 06, 2007 1:44 am 
Newbie

Joined: Thu Feb 01, 2007 6:44 am
Posts: 4
Location: India
Hi Dharmendra,

Won't be able to post the code. Apologize for the same.
Was hoping that the error was a standard one for which there might be some general pointers.
Thanks a lot for looking into it.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Feb 09, 2007 9:45 am 
Newbie

Joined: Thu Feb 01, 2007 6:44 am
Posts: 4
Location: India
Just to bring a closure to the issue I had put in....
I was facing the error because of an improper trigger in the database. The trigger was updating the record verssion causing synch problems with the hibernate session.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 7 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.