-->
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.  [ 4 posts ] 
Author Message
 Post subject: Question about detached objects and stale state exceptions
PostPosted: Thu Apr 27, 2006 1:58 pm 
Newbie

Joined: Thu Mar 16, 2006 1:12 pm
Posts: 10
Hello all,

I've got a question about how to deal with a StaleStateException.

Let's say I start a session and grab a bunch of objects out of my DB like so:

Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(MyObject.class);
criteria.add("status", 1);
List myObjectList = criteria.list();

and let's say the above returns a list of 100 instances of MyObject. Now, I want to iterate through each of the 100 instances and modify them in some way like so:

for (int i = 0 ; i < myObjectList.size(); i++) {
MyObject o = (MyObject)myObjectList.get(i);
o.setStatus(new Integer(2);
session.save(o);
session.commit();
Thread.sleep(1000); // go to sleep to cause a bad situation
}

And I run the above - and the first 19 objects get modified correctly - but when I get to the 20th object in the list of 100, I get a StaleStateException (because someone else has updated the object since I read it) - I'm using the version method as described in "Hibernate In Action" where there is a version column in my table.

I'm OK with "giving up" on modifying the 20th object and I want to move on to the remaining 80 objects still in the list. But if I catch the StaleStateException and try do continue with the 21st item in the collection I still get a StaleStateException - not from the 21st item - but from the 20th item which is still modified (and stale) in my session's cache. Basically, I've been able to update the first 19 items - but I can't update the remaining 80 objects because the 20th is "blocking" me.

How should I handle this? I've heard some people say that once you get an exception - *any* exception - in your session, you should close the session - that it should no longer be used. Is this true? Do I really have to do something like the following?

Session session = HibernateUtil.getSession();
Transaction transaction = session.beginTransaction();
Criteria criteria = session.createCriteria(MyObject.class);
criteria.add("status", 1);
List myObjectList = criteria.list();
transaction.commit();
session.close();
for (int i = 0 ; i < myObjectList.size(); i++) {
MyObject o = (MyObject)myObjectList.get(i);
session = HibernateUtil.getSession();
transaction = session.beginTransaction();
session.lock(o, LockMode.NONE); // attach detached object to session
o.setStatus(new Integer(2);
session.save(o);
session.commit();
Thread.sleep(1000); // go to sleep to cause a bad situation
}

This is an awful lot of sessions being created - is this how it should be done? Can't I "remove" the offending 20th object from my original session's cache some how?

Any light you can shed would be appreciated.

-john


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 27, 2006 9:29 pm 
Regular
Regular

Joined: Thu Jul 29, 2004 11:55 pm
Posts: 75
I will list a few potential solutions:

1) You could refresh each object before you do the update - this would ensure that each object is up-to-date
* there may be a performance hit associated with this if you are not using a sescond level cache - you may want to test to verify

2) If you don't care about the changes, you could use merge
* if the other changes are required then this could have negative side-effects and should ONLY be used if your business logic supports this

3) if you get the exception, you could reload the list, but if there are a lot of chnages to the list, you may never get out of this.

Hope this gives you some ideas and helps you find a solution.


Top
 Profile  
 
 Post subject: Isn't session invalid once you get *any* exception?
PostPosted: Sat Apr 29, 2006 2:55 am 
Newbie

Joined: Thu Mar 16, 2006 1:12 pm
Posts: 10
I appreciate your ideas about how to recover from a StaleStateException - but it still leaves the open question: once you receive a StaleStateException, should you even *try* to recover? I've heard that once you get ANY exception, that you should rollback any outstanding transactions and close the session. I don't know if this is true or not. I wish I could find a definitive answer.

I like your idea about refresh. However, I'd still like to find out if evict() couldn't be used to remove this "stale" object from my cache. Also, another idea - instead of doing a refresh (which WOULD go to the database), perhaps I could "store" the original state of the object before I change it - then, if I get a StaleStateException, I could "restore" the original saved state. Perhaps if I did this, the session would be smart enough to realize that I had NOT actually changed the object - and, therefore, wouldn't try to write any changes from the DB... Don't know if hibernate is this smart or not...

Anyone out there have an answer?

Any light you can shed would be very appreciated.

-john


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 29, 2006 5:06 am 
Beginner
Beginner

Joined: Thu Apr 20, 2006 3:44 am
Posts: 32
can we have following pseudo code

Get the data using session object.
Now close the session, so that your object is detached.
Modify the object.
Next time when you try to save the updated object, you should have an exclusive lock so that no one else would be able to "modify" the data which you are trying to insert.....

But having said that, we have to find out what will happen to concurrenct........meanwhile you can try this out....

Sudhir


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 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.