-->
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: Why does session.close() throw HibernateException?
PostPosted: Thu Jan 29, 2004 7:59 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
I am frustrated by this:

try { doSomethingWithHibernate(); threadLocalSession.close(); }
catch (HibernateException ex) {
// now I just want to deal with the exception... but I still have to close the session!
try { threadLocalSession.close(); } catch (HibernateException) { /* ignore it! */ }
}

In other words, when something goes wrong, Hibernate still wants you to close the session. I would like to do that in my catch clause. But because session.close ALSO throws HibernateException, I have to write ANOTHER catch clause, and it's not clear what I can *do* with the session's failure to close!

So why does session.close() throw an exception, what should I do if it does, and what is the best pattern for closing sessions in catch or finally clauses?

Cheers!
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 8:02 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Session.close() throws an exception because it calls JDBC Connection.close()


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 8:11 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
You are a god among men, Gavin, and I am a huge fan.

That said, is this the right pattern to use? (taken from one of our SLSB's, aka our service layer):

public void deleteList (Long sourceListId) throws NFNoSuchEntityException {
try {
BeanAssetManager.deleteList(sourceListId);
} catch (HibernateException e) {
throw new NFInternalErrorException("Could not delete list with id "+sourceListId, e);
} finally {
try { Persistence.closeSession(); } catch (HibernateException ex) {}
}
}

Seems to me this closes the session regardless of what exceptions could fly out of the service layer. Previously I had the closeSession inside the try (rather than in the finally), and I have verified that that results in errors like this if NFNoSuchEntityException is thrown:

2004-01-29 15:52:19,410 : Pool.freeConnections : WARNING: Connection not closed by caller
2004-01-29 15:52:19,473 : XAResourceImpl.end : END without START or mixed xids: 3e9903073c470_0_3e9903073c470_0_ != null
2004-01-29 15:52:19,473 : Pool.closeConnection : Pool: Exception while delisting resource:javax.transaction.SystemException: Cannot send XA end:javax.transaction.xa.XAException

This doesn't seem good.

My original question does remain, though: what is a caller expected to *do* if session.close() throws an exception? This might be a question for JDBC itself, but still... what do *you* do in this situation, Gavin?

Thanks again for Hibernate!
Cheers,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 8:17 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Ay, stop that, I gotta big enuff ego as it is....


I would probably wrap it in my InfrastructureException and report a generic failure to the user.

But I think its probably reasonable to just log a WARN and continue, if and only if you know that the transaction was successful (looks like you don't in your case).

Personally, I always centralize all exception handling in my systems - which is a lot harder with the session facade pattern, since the stupid EJB spec doesn't provide interceptors. Thats one reason why I use command pattern instead of session facade (I can have my own interceptor fwk).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 8:35 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Hm. So you're saying that session.close() could throw an exception if the transaction itself fails?

But session.close() doesn't mean the container has committed the transaction, does it? It just finalizes the session itself. The transaction could still fail after my session bean has entirely returned (and after session.close() has completed successfully). Right?

Or is it the case that if the transaction is going to fail, session.close() is *when* it will fail?

Would doing a session.flush() inside the try{} block cause any transaction failures to happen there rather than inside session.close(), or are there failures that could happen only inside session.close()?

Thanks again,
Rob


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 9:21 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
The transaction could still fail after my session bean has entirely returned (and after session.close() has completed successfully). Right?


Exactly, this is always possible. Thats why your code is probably not quite safe.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 9:29 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
(I am really sorry to reply to you so much, and I really appreciate your helping me dig to the bottom of this. This is one of those times where if we were in the same room you could have explained it to me in 30 seconds, but the round-trip latency and limited text bandwidth is killing our performance ;-)

But how *could* my code be safe in that case? What you're saying is that even if I do:

try { someHibernateThing(); }
catch (HibernateException ex) { throw MyInfrastructureException(ex); }
finally {
try { ThreadLocalSession.close(); } catch (HibernateException ex) { throw MyInfrastructureException(ex); }
}

...and someHibernateThing() *doesn't* throw any exceptions, and the finally block *doesn't* throw any exceptions, and the Hibernate session is happily closed, and I didn't throw any MyInfrastructureExceptions...

... the transaction could *still* fail when the container goes to commit the transaction, and who knows *what* the container will do (probably throw *its* MyInfrastructureException?!).

In other words, it looks to me like if the container is responsible for the commit, and if the commit can fail after my code has completely finished executing and all Hibernate sessions are closed, then there *is nothing I can do* to be more safe in that situation.

So I don't understand why you say "Exactly, that's why your code is not quite safe," when in the scenario I was describing, there's nothing my code *can* do to *be* more safe!

Or did I just miss your point, and are you approaching exasperation with my denseness? ;-)
Cheers!
Rob

(p.s. when's that book gonna be done? I'll be reviewing chapter 6 this weekend...)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 29, 2004 9:34 pm 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
The book will be in print second quarter 2004, but we hope to have some chapters earlier on the Manning Early Access Program.

_________________
JAVA PERSISTENCE WITH HIBERNATE
http://jpwh.org
Get the book, training, and consulting for your Hibernate team.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 30, 2004 8:12 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Quote:
In other words, it looks to me like if the container is responsible for the commit, and if the commit can fail after my code has completely finished executing and all Hibernate sessions are closed, then there *is nothing I can do* to be more safe in that situation.

So I don't understand why you say "Exactly, that's why your code is not quite safe," when in the scenario I was describing, there's nothing my code *can* do to *be* more safe!


The code you have just shown that throws a MyInfrastructureException is safe. The previous version, which swallowed the exception, is a little bit less safe.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 30, 2004 8:15 pm 
Expert
Expert

Joined: Thu Jan 08, 2004 6:17 pm
Posts: 278
Okey dokey :-) I'll stick with that pattern then. Thanks!
Cheers!
Rob


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.