-->
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.  [ 10 posts ] 
Author Message
 Post subject: Optimistic Locking with stored version
PostPosted: Mon Feb 06, 2006 12:17 am 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
I'm trying to use Hibernate optimistic locking (version) with Spring.
I don't save any Hibernate session or detached object in httpSession.
I stored my object id and version in html page as hidden fields and when I update the object, I get the object from Hibernate and set the version to the version I stored as a hidden field.
The optimistic locking does not work unless after I load my object from Hibernate with the Id and evict the object and set the version.
Without the evict, Hibernate always use the version from the 'original' object. My set version does not work.

Here is an example:

MyClass myObj = (MyClass) template.get(MyClass, id);
temlate.evict(myObj);
myObj.setVersion(myVersion);
template.update(myObj);

My question is, why do I have to evict the object. Shouldn't hibernate always use my version to do optimistic locking?

Is there anyway I can use the hidden field approach without having to do the evict?

Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 06, 2006 1:11 am 
Senior
Senior

Joined: Sat Jul 17, 2004 5:16 pm
Posts: 143
This doesnt really make sense.

If you are getting a row from the DB, and setting the version, then you arent going to persist that version... which is weird. Might as well just instantiate a new object, set the id, and the version, and the other fields, and persist that... right?

I think the bottom line of why, is hibernate is trying to solve more problems than it creates. If it doesnt trust the bean, then it can know when people change the version field, which is not common and is a cause for error.

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 06, 2006 12:10 pm 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
Here is how it works:
(1) If no one else modified the data, the version should be the same. There shouldn't be an optimistic locking exception.
(2) If someone modified the record, the 'old' version number should cause an optimistic locking exception.

My goal is to use hidden field values rather than store some objects or hibernate session to implement optimistic locking in a Struts type web application. Is there any way to do it other than using httpSession to store disconnected hibernate session or objects?



mchyzer wrote:
This doesnt really make sense.

If you are getting a row from the DB, and setting the version, then you arent going to persist that version... which is weird. Might as well just instantiate a new object, set the id, and the version, and the other fields, and persist that... right?

I think the bottom line of why, is hibernate is trying to solve more problems than it creates. If it doesnt trust the bean, then it can know when people change the version field, which is not common and is a cause for error.

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 06, 2006 12:39 pm 
Senior
Senior

Joined: Sat Jul 17, 2004 5:16 pm
Posts: 143
First of all this is really not ideal security where you let the user have the opportunity to manipulate fields in a hidden field (easy to do).

Second, assuming you have worked out the security, can you not just instantiate an object, put the id and version in there, all the other fields, attach, and store?

Chris


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 07, 2006 2:15 pm 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
I agree with you on security. I do security on different layers (where id is validated).
What I'm doing is get the user input, set the values I need to change and update. The problem is I have to evict the object to make optimistic locking work. I do not store every thing for a record as hidden field or in session. That's the reason I have to get the object from hibernate. Are you suggesting I should do something like this:

MyClass aObj = new MyClass();
aObj.setId(id);
aObj.setValue(aValue);
aObj.setVersion(aVersion);
template.update(aObj);

The problem is I don't keep all the fields as hidden fields and I don't store them all in session either. I want hibernate to handle that for me.

Thanks for your help.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Feb 07, 2006 10:51 pm 
Senior
Senior

Joined: Sat Jul 17, 2004 5:16 pm
Posts: 143
ok, then evict the object. why do you not want to evict? or just check the version when you set it and if different than throw exception.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 09, 2006 3:24 am 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
If I just check the version and throw exception, in a highly concurrent environment, it won't help. What I am expecting is:
update xxx setvalues xxxx where version = xxx

Manually checking version is doable but the reason I'm using hibernate is to avoid such kind of things.
Using evict is 'ok', but doesn't make any sense. If I have version for optimistic locking why hibernate doesn't use it less it's a detached object?

The way I'm using optimistic locking isn't something documented in hibernate reference doc. I just want to see how other people handles it in similar situations: hibernate+spring+no object in httpsession

Thanks,


Top
 Profile  
 
 Post subject:
PostPosted: Thu Mar 02, 2006 12:26 am 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
I finally found a solution:

(1)Use Hibernate Interceptor
(2)In flushDirty check the timestamp field
if(currentTime.getTime() < oldTime.getTime()){
throw OptimisticLockingException();
}


Top
 Profile  
 
 Post subject:
PostPosted: Wed Mar 22, 2006 7:48 am 
Beginner
Beginner

Joined: Tue Oct 07, 2003 4:41 am
Posts: 21
Thanks for posting your solution.

I've hit the same problem, and I agree with you that it makes perfect sense to avail of the optimistic concurrency in the way you describe.
So long as no-one has access to modify the field holding the Version, then the mechanism is not compromised.
I wanted to do it this way to avoid having to hang on to the Hibernate session.

I still don't see why simply setting the Version field on my POJO shouldn't cause Hibernate to use that value in the subsequent SQL UPDATE.

regards

John


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 31, 2006 11:35 pm 
Newbie

Joined: Sun Feb 05, 2006 11:56 pm
Posts: 6
Here is what I'm using now.

(1) Store the version/timestamp as hidden field
(2) Read back the object from db/hibernate
(3) Set the version/timestamp

In the Hibernate Interceptor (flushDirty), check if the new objects' version/timestamp is older than the 'old' object's version/timestamp.
If it is, then throw a staled object exception.

Say the new state is Obj2, the one read from database is Obj1,
if(Obj1.version < Obj2.version) // we know right away there is an optimistic locking exception

if(Obj1.version == Obj2.version) // we don't need to change anything, let hibernate handle the potential optimistic locking exception

if(Obj1.version > Obj2.version) // this happens when Hibernate reset the version/timestamp and called this flushDirty again. I don't know why but it's kind make sense if you changed the version/timestamp then it got called again. Don't do anything here.

The only exception is in a clustered environment, the Obj1.version > Obj2.version senrio could happen and should throw a optimistic locking exception.
For this reason, I'm using version now rather than timestamp. Timestamp caused me a lot of pain. One of them is Date.equals(Timestamp) but Timestamp.notEqual(Date) issue and a lot of other things.

Good luck


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