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.  [ 6 posts ] 
Author Message
 Post subject: Versioning
PostPosted: Thu Jan 11, 2007 9:07 pm 
Newbie

Joined: Thu Jan 11, 2007 8:41 pm
Posts: 3
I have made it my mission to replace the crumbling awful hand-coded DAO apps at my current contract with a nice alternative using hibernate. I think this is the last stumbling block to prove that it can work. (most of the developers are converted PL/SQL programmers who like to have their meetings in SQL and would love SQL on Rails)

We have both a Last Update Date column, and a Created Date column on all tables. There is a trigger on insert that populates the current DB timestamp into the Created Date column, and another trigger on Update that populates the Last Update Date column.

In order to get the optimistic locking working correctly for existing records, I have used the Last Update Date column with the timestamp mapping:

Code:
<timestamp column="LAST_UPD_DATE" name="lastUpdate" generated="always" />


But, it's not "always" generated by the database - only on updates. So when I create a new transient object, the version is null, and the new object is persisted, but then the subsequent SELECT gets a null value for the version, and treats the object as unsaved, eventually producing a TransientObjectException. The data is saved but my object on the Java side can't be modified anymore because now the optimistic locking fails.

I read in the manual:
Quote:
A version or timestamp property should never be null for a detached instance, so Hibernate will detact any instance with a null version or timestamp as transient, no matter what other unsaved-value strategies are specified.

http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-version
So that means I can't indicate the object is actually saved by another means.

Is there a strategy that would handle this? I know the best solution is to fix the trigger so the Last Update Date is not null for a record in the DB, but the DBA is the sort who greatly enjoys making developers crazy. It seems that if I could have insert="true" and generated="always", it would do the right thing, but it's not allowed:
Code:
org.hibernate.MappingException: cannot specify both insert="true" and generated="always" for property: lastUpdate

I have poked around the code some but I'm not sure where to look to find a way to do this.

Thanks!

-Alex

[ Hibernate 3.1.3, Oracle 10g database ]


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 10:01 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Just get the create triger to set the date on both fields.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 11, 2007 10:02 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
Alternatively - dump the triggers and use a hibernate event/trigger to update the fields for you. Examples are on the wiki.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 12, 2007 10:40 am 
Newbie

Joined: Thu Jan 11, 2007 8:41 pm
Posts: 3
david wrote:
Alternatively - dump the triggers and use a hibernate event/trigger to update the fields for you. Examples are on the wiki.


I have found the Interceptor / EmptyInterceptor classes that allow me to twiddle the Java object, but I haven't been able to find the hibernate event or trigger you're referring to. That sounds like a good solution, could you post a link?

Thanks!


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 13, 2007 5:33 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 7:19 pm
Posts: 2364
Location: Brisbane, Australia
See these and related pages
http://www.hibernate.org/195.html
http://www.hibernate.org/48.html
http://www.hibernate.org/318.html


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 17, 2007 6:04 pm 
Newbie

Joined: Thu Jan 11, 2007 8:41 pm
Posts: 3
It turns out none of the event listeners help. I can set the version into the Object in a listener, but the UPDATE statements inside the Persister always have a WHERE LAST_UPD_DATE=? clause in them, and since that's null in the database I'll always have optimistic locking issues.

It seemed very daunting to try to write a JDBC call inside the event listener, since I'd have to figure out the name of the database table, as well as all the keys (we have a scary number of composite keys) for the update. I need this to be generalized since I have the same problem for all 100+ tables, and don't want to write a listener for each one.

I ended up making a view, which I'll have to have for every table:

Code:
create view APPL_ATTACHMENTS as select a.*, NVL(LAST_UPD_DATE, CREATED_DATE) MODIFIED_DATE from APPL_ATTACHMENTS_T a


This is a little annoying but works nicely with hibernate's generated="always" and doesn't mess up the DBA's bookkeeping too bad.

Thanks!


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