-->
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: Struts / "Select before Update" / version check pa
PostPosted: Fri Jun 02, 2006 11:19 am 
Newbie

Joined: Thu Jun 01, 2006 12:24 pm
Posts: 3
Greetings all, my first foray into the message groups, so forgive is a thread already exists (I've been searching!) In retrospect, sorry for the long message - I'm not great with all the terminology.

This is a c concurrency issue - I don't understand the best way to deal with it (the code below works, but is there a better way to control this?) I'm not a subject matter expert, so forgive my ignorance as I learn...

I'm working w/ Spring 1.2x / Hibernate 3.1 in a Struts frontend enviro:

Here's the issue: I do NOT want to store the actual (detached) domain POJO into an HttpSession, etc., but will do so if need be if I can find a better way around this issue... My struts forms don't represent the entire domain object, just a few fields that it has. Nor can I move to Spring Web - stuck w/ Struts for the time being...

On the callback for an update from a simple web form, I move the struts fields that were edited (including the hidden version field) back into the domain object AFTER issuing a getById (to fill in the fields that the user doesn't get access to!) The problem is, that when I move the struts version tag into the POJO, no matter what the value is, an update is always successful (aka - Hibernate seems to maintain the version check / value separately in the Session, not referring to the POJO value at this point). As a "fix" to this, after updating the POJO, I evict and then lock it - that does the version check stuff successfully!

Is there a better pattern / way to deal with this? I could change the call to get the current object w/ a version check in the query, but don't want to deal with issues why I get 0 rows back (is the row deleted, is the version incorrect, etc.?) (If I don't execute an evict/lock, the update always works regardless of the POJO version value).


Here's a flow as stands now:

0) User requests to edit a "Buiness Rule" row.

1) Get Object by ID.

2) Copy editable fields from POJO domain object to struts form (including the retrieved version # from the read to a hidden field on the web form)

(User makes edits, submits form)

3) Get the domain Object by ID. (based on the id in the Struts form)

4) Populate changes into the Domain Object (move struts fields into POJO fields, including the "original" version value)

5) Evict the Object

6) Lock the Object (if the version if out of synch, I get the expected "dirty" result)

Here's a simple code snippet:

Code:
public void update(BusinessRule bR) throws Exception {
      
   HibernateTemplate ht = getHibernateTemplate();
      
   BusinessRule originalBR = getById(bR.getPlayerId());
      
   originalBR.setRuleNm(bR.getRuleNm());
   originalBR.setVersion(bR.getVersion());
                               
...
      
   ht.evict(originalBR);
   ht.lock(originalBR, LockMode.READ);  //versions not the same, dirty exception!!
      
      
   ht.saveOrUpdate(originalBR);


Thanks.
Psantt.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 02, 2006 12:01 pm 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
We always do like this:

1. get object by id from hibernate
2. render object, fill in into form the editable fields

then the user edits and submits, now:

1. get object by id from hibernate
2. update the persistent object with form information
3. saveOrUpdate, commit.

I don't understand why you are using an extra object instance.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 02, 2006 2:19 pm 
Newbie

Joined: Thu Jun 01, 2006 12:24 pm
Posts: 3
The big problem is that if user 2 came in and updated the record between the time the user 1 pulled the record, and then submitted it for update, I haven't been able to get the version checking to work successfully (different from a transaction or pessimistic lock - I drop the transaction when the user successfully retrieves the data for update).


This is the goofy combination I'm trying: (I will probably go for a save object to user session, then reattach if I can't come up with anything)

*** When user submits for update, I "re-retrieve" the data object before applying any changes from the web form (just to get certain fields that I don't want to store in an HttpSession or put into hidden struts variables @ the web tier).

*** When I try to apply those changes (including trying to update the version field), and then saveOrUpdate - the save or update works fine, but disregards the version I updated the object with in order to do the update... whatever the version number is on the db when I retrieved the object, that is the version # it does in the update! -- this is fine while working within a transaction, but I'm detaching everything for the web tier edit.

I'm beginning to realize that version wasn't designed for what I'm trying to do, but I'm suprised I can't override it by modifying the version on the POJO directly - and letting Hibernate figure out that the version numbers don't synch up - and then throw back a dirty exception.

(also, I was wrong - the detach / reattach logic doesn't update the db at all!)

Thanks...

Psantt...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jun 02, 2006 3:04 pm 
Regular
Regular

Joined: Tue Nov 16, 2004 6:36 pm
Posts: 62
Location: Zürich
I see, we ususally create "shadow" objects to avoid this problem, i.e. create a new object as a copy from the old one and save it (already upon retrieving) leaving the users id in some field. Then upon final save (accept) the shadow object is copied back to the original one (and automatic historization is done etc.) However this implements a special review process (with reject/accept, alert notification etc).

For simpler situations, could you not just save the version of the object in the HTTP sesssion, then before submitting the users modification to the database, check that the version has not been changed:

1. get object by id
2. render and fill form based on object value
3. save the objects version in the http session

after user modification and submit:

1. get object by id
2. compare objects version with the version you retrieved before, if no match then exit with some warning
3. update object based on form contents
4. saveOrUpdate, commit


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.