-->
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.  [ 8 posts ] 
Author Message
 Post subject: update() + named sql query in same transaction?
PostPosted: Fri Mar 27, 2009 7:40 am 
Beginner
Beginner

Joined: Wed Dec 10, 2008 5:59 am
Posts: 47
Hi,

I have a transaction which simply updates an element in table A. However, a number of other related elements in another table B needs to be updated whenever the element in table A is updated.

I achieve this now by doing the following:

Code:
currentSession.beginTransaction();
manager.update(currentNode);
currentSession.getTransaction().commit();

currentSession.beginTransaction();
//This is a call to a native SQL query.
manager.executeKeywordChanged(currentNode);
currentSession.getTransaction().commit();


1. If the first block fails - everything is fine. No damage done.
2. If the second block fails - then suddenly the element in table A is updated but the related elements remain unchanged.

The main issue is that if i put both the update() and executeKeywordChanged() calls in the same transaction block, then executeKeywordChanged() will be flushed immediately when i invoke the method (no matter what) as it is a native SQL query. The save() will not be flushed before commit() is invoked.

The dream scenario here would be as follows, where update() and executeKeywordChanged() would be flushed sequentially on commit().

Code:
currentSession.beginTransaction();
manager.update(currentNode);
manager.executeKeywordChanged(currentNode);
currentSession.getTransaction().commit();


However, this seems not to be the case. Any others with experience on this?

[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 7:42 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
You can manually execute a Session.flush() before execute the native query. Eg.

Code:
currentSession.beginTransaction();
manager.update(currentNode);
currentSession.flush();
manager.executeKeywordChanged(currentNode);
currentSession.getTransaction().commit();


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 7:46 am 
Beginner
Beginner

Joined: Wed Dec 10, 2008 5:59 am
Posts: 47
Ok,

But what i would like to achieve is that executeKeywordChanged() only is invoked if update() succeeds, and update() should be rolled back if executeKeywordChanged() fails.

Should i maybe look into database triggers for this problem?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 7:52 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Yes, that is exactly what happens in the example I posted. I assume that you have proper try/catch handling around the entire piece of code. eg.

Code:
try
{
   // code from above
}
catch (Exception ex)
{
   currentSession.getTransaction().rollback();
}


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 8:36 am 
Beginner
Beginner

Joined: Wed Dec 10, 2008 5:59 am
Posts: 47
My code looks as follows:

Code:
try {
sessionFactory  = com.tracker.db.SessionFactoryHelper.getSessionFactory();
currentSession  = sessionFactory.openSession();
manager = new KeywordManager(currentSession);

currentSession.beginTransaction();
//Perform updated
currentSession.getTransaction().commit();

} catch (org.hibernate.StaleObjectStateException e) {
currentSession.getTransaction().rollback();
//Synchronize object with newer version in database

} catch (Exception e) {
if (currentSession != null) { currentSession.getTransaction().rollback(); }

} finally {
if (currentSession != null) { currentSession.close(); }
}


Just to make sure that i understand this completely: what you are saying is that if i change the transaction block to contain the following - then everything will be ok?

Code:
currentSession.beginTransaction();
manager.update(currentNode);
currentSession.flush();
manager.executeKeywordChanged(currentNode);
currentSession.getTransaction().commit();


I just though that by invoking flush(), the changes would be written to the database. And, as a consequence of this, if the executeKeywordChanged() failes, then the changes made to currentNode would already be written to the database?

Is the changes made by update() + flush() actually rolled back/reverted from the database with an SQL statement if the executeKeywordChanged() fails?


Top
 Profile  
 
 Post subject: Tested solution, and it seems to work.
PostPosted: Fri Mar 27, 2009 8:41 am 
Beginner
Beginner

Joined: Wed Dec 10, 2008 5:59 am
Posts: 47
Alright,

I tested your solution and it works fine! I just thought that as long a session was flushed, then things would be written to the database and things couldn't be rolled back...but it seems that my Hibernate knowledge has a few flaws :-)

Thank you very much for your speedy and great help!


Top
 Profile  
 
 Post subject:
PostPosted: Fri Mar 27, 2009 8:42 am 
Expert
Expert

Joined: Wed Mar 03, 2004 6:35 am
Posts: 1240
Location: Lund, Sweden
Quote:
I just though that by invoking flush(), the changes would be written to the database.


Yes they are written to the database and that is good since you need the updated values in native query...

Quote:
And, as a consequence of this, if the executeKeywordChanged() failes, then the changes made to currentNode would already be written to the database?


Not true. When you rollback the transaction everything that has been written is undone.

Quote:
Is the changes made by update() + flush() actually rolled back/reverted from the database with an SQL statement if the executeKeywordChanged() fails?


Yes, it is the call to currentSession.getTransaction().rollback() that triggers this.


Top
 Profile  
 
 Post subject: OK
PostPosted: Fri Mar 27, 2009 8:49 am 
Beginner
Beginner

Joined: Wed Dec 10, 2008 5:59 am
Posts: 47
OK!

Thanks a lot for your explanation!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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:
cron
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.