-->
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.  [ 5 posts ] 
Author Message
 Post subject: Version check not throwing StaleObjectStateException
PostPosted: Fri Oct 28, 2005 6:05 pm 
Newbie

Joined: Wed Aug 24, 2005 5:06 pm
Posts: 3
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

[b3.0.5[/b]

[b]Mapping documents(Fragment):
<class
name="gov.ca.doj.sins.riss.model.Submission"
table="SUBMISSIONS" select-before-update="true" dynamic-update="true" optimistic-lock="version"
>
...
...
<timestamp name="modifyTimestamp" column="MODIFY_TIMESTAMP" />

[/b]


Hi,

We use modify_timestamp as our managed versioning.

We have a scenario in a web application where we do the following steps:

(1) Retrieve event with id="1234". (called eventDTO1 which reads its values from event POJO) (modify timestamp say 1 pm)

(2) Retrieve another event with same id="1234" (called eventDTO2 which reads its values from event POJO) (modify timestamp say 1:10 pm)

(3) Make some updates in presentation layer to some attributes of eventDTO2 and send it to persistence layer for update. Persistence layer retrieved event POJO and updated its attributes from eventDTO2. Everything is updated succesfully and modify timestamp is updated to current time (say 1:20 pm)

(4) Now make some updates to eventDTO1 and send it to persistence layer, persistence layer retrieved event POJO and updated its attributes from eventDTO1. we expected to see StateObjectStateException but everything gets updated successfully and modify_timestamp is updated to say 1:30 pm (which was when we did update for event)

When I look at the reason why the update went through succesfully, I found that the following query was used:
2005-10-28 13:55:15,969 [main] DEBUG org.hibernate.SQL - update SUBMISSIONS set MODIFY_TIMESTAMP=?, MODIFY_ID=? where ID=? and MODIFY_TIMESTAMP=?

The actual query with values (in pseudo-code) looks like this:
update SUBMISSIONS set MODIFY_TIMESTAMP="1:30 pm", modify_id='ABCD' where is='1234' and MODIFY_TIMESTAMP="1:20 pm";

(this query will always succeed since the value of MODIFY_TIMESTAMP used in where clause is value stored in database (previousState) and not currentState which will be set from presentation layer)

The MODIFY_TIMESTAMP that we should expect to be used in the where clause is the one held in eventDTO1 (which was 1:10 pm)
But the value that was used in MODIFY_TIMESTAMP in where clause was 1:20 pm and not 1:10 pm which would have triggered StaleObjectStateException. 1:20 pm was time when eventDTO2 in step 3 was successfully updated. I found these values reliably by using p6spy.

Hibernate should be using the modify_timestamp value that is coming from presentation layer and not the current modify_timestamp value stored in database.

I am using following attributes in all in hbm xml files:

<class
name="gov.ca.doj.sins.riss.model.Submission"
table="SUBMISSIONS" select-before-update="true" dynamic-update="true" optimistic-lock="version"
>
...
...
<timestamp name="modifyTimestamp" column="MODIFY_TIMESTAMP" />

Note: We posted it to Hibernate JIRA thinking it is a bug, but it has been rejected without any explaination. We are at loss how to use Hibernate's stale data check feature. Please help us otherwise we will end up having to write our own code for this, which we want to avoid.

Anil and Virinder


Top
 Profile  
 
 Post subject:
PostPosted: Sat Oct 29, 2005 6:49 pm 
Beginner
Beginner

Joined: Thu Jan 22, 2004 8:22 pm
Posts: 48
I've used optimistic locking with timestamps in several projects without problems. The one major differance I can see between the way your doing things and the way I'm doing them is that I directly use the object instances returned by Hibernate in steps 1 and two to perform the updates in steps 3 and 4. In your description you retreive new instances from Hibernate in steps 3 and 4 and then change them and allow them to save.

It might be the case that in step 4 Hibernate knows the instance originally had a timestamp of 1:20. It sees your attempt to alter the timestamp as a update and uses the old value for the stale check to see if anyone has changed the row since it was selected. Since it hasn't been altered it allows the update of the timestamp to proceed.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 31, 2005 3:37 pm 
Newbie

Joined: Wed Aug 24, 2005 5:06 pm
Posts: 3
Hi JustKeith,
Thanks for your reply.
Please note that we are looking for Application transaction application lock, that is, an entity is retrieved, session is closed, the entity data is displayed to a web browser. The entity is updated and sent over to the service layer (as a DTO).

To update the entity, a new session is opened, entity is retrieved and updated with the data in the DTO. Now we update modifytimestamp with the value which was intially retrieved and carried over to the presentation layer.

For application transaction optimistic lock, shouldn't Hibernate use the modifytimestamp that we are carrying over from web instead of the value retrieved in the current session?

Please note that we are looking for optimistic lock allowing user think time to update data and want to fail the update if meanwhile some other user retrieved the same data and updated it.

"Hibernate In action Book" calims to provide this feature.

Thanks
Anil


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 31, 2005 4:32 pm 
Beginner
Beginner

Joined: Thu Jan 22, 2004 8:22 pm
Posts: 48
I'm going to start by saying I could be completely wrong here. I think Hibernate might be using the value of the timestamp that was in the field when the object was selected from the database for the lock check. If you read teh optimistic concurrancy control chapter in teh manual you'll notice they don't talk about a model like yours. What your doing looks to Hibernate like Long session and automatic versioning and it probably sees the attempt to change the timestamp property as simply a update not as a attempt to change what timestamp to use for the version check.

Without altering your architecture I'm not sure how to get automatic version checking working for you. I normally use detached objects and automatic versioning. Basically the instances returned by Hibernate from the database are used as my DTO and are held in the session during the user think time.

Sorry i couldn't be of more help. Good luck.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 07, 2005 7:08 am 
Newbie

Joined: Mon Nov 07, 2005 6:50 am
Posts: 2
Hi anilkb,

I also use optimistic locking with DTOs instead of detached value objects and I have ended up with the same problem as you.
The only way I was ab le to achieve proper version checking was by using the following sequence in the update transaction:

1. Read the value object from the database
2. Evict the object from the session using
session.evict(vo)
3. Merge the changes inclusing the original value of the timestamp/version field.
4. Call session.update(vo) or session.saveOrUpdate(vo).

There is a bit of additinal complexity with the above approach in the case of composite value objects. In order to allow for version checking on child objects I intend to include cascade="evict" for all child references.

In summary however I can't think of a good reason for the current Hibernate behaviour and I consider it a bug unless someone explains the idea behind it.


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