|
From: Juergen H. <ju...@in...> - 2005-04-27 16:30:53
|
Well, SessionFactoryUtils.closeSessionIfNecessary already catches all
declared exceptions and logs them at error level, exactly because it is
usually called in finally blocks, where the original exception should not
get overridden.
An IllegalStateException is simply unexpected there. I would have expected
an IllegalStateException thrown by a custom type to be wrapped in a
HibernateException. Anyway, I've added a catch(RuntimeException) block
there, logging any RuntimeException at error level too instead of
propagating it.
Thanks for pointing this out, Nick!
Juergen
-----Original Message-----
From: spr...@li...
[mailto:spr...@li...]On Behalf
Of Nick Minutello
Sent: Monday, April 25, 2005 4:14 AM
To: spr...@li...
Subject: [Springframework-developer] OpenSessionInViewFilter - can lose
filter-chain exception causes
Chaps,
Just having spent some time tracking down a problem (a Hibernate
Session leak, in fact) - it seems that The OpenSessionInViewFilter is
hiding some root-cause information that I need.
The problem with try-finally's (ie no catch) is that if we are in the
finally-block because of an exception, and then we get a new exception
in the finally block, the original exception will be lost :-o.
In my particular case, the call to closeSession() on line 181 is
resulting in an IllegalStateException (way deep in a custom type in
hibernate).
This means that the exception coming out of filterChain.doFilter() on
line 172 is lost.
In my particular case the IllegalStateException is occuring as a
result of the original exception.
171 try {
172 filterChain.doFilter(request, response);
173 }
174
175 finally {
176 if (!participate) {
177 if (isSingleSession()) {
178 // single session mode
179 TransactionSynchronizationManager.unbindResource(sessionFactory);
180 logger.debug("Closing single Hibernate session in
OpenSessionInViewFilter");
181 closeSession(session, sessionFactory);
182 }
183 else {
184 // deferred close mode
185 SessionFactoryUtils.processDeferredClose(sessionFactory);
186 }
187 }
188 }
A better approach is to add a catch block and record any exception
that comes out of the filter chain - in case we get a new exception in
the finally bock:
We then have to make a choice about which we throw out. IMO, the first
exception is more interesting (but in any case, we throw one and log
the other- we dont want to lose any information)
Here is what I usually do in this situation:
Exception originalException;
171 try {
172 filterChain.doFilter(request, response);
173 }
174
catch (Exception e) {
originalException = e;
}
175 finally {
try {
176 if (!participate) {
177 if (isSingleSession()) {
178 // single session mode
179 TransactionSynchronizationManager.unbindResource(sessionFactory);
180 logger.debug("Closing single Hibernate session in
OpenSessionInViewFilter");
181 closeSession(session, sessionFactory);
182 }
183 else {
184 // deferred close mode
185 SessionFactoryUtils.processDeferredClose(sessionFactory);
186 }
187 }
catch (Exception e) {
if (originalException != null) {
// yikes we have an exception while cleaning up after
the first one!
log.error("Error while cleaning up after exception from
filter chain", e);
throw originalException;
}
throw e;
}
188 }
In some cases, I would tend towards catching Error as well as Exception.
Its quite conceivable to get a java.lang.Error - like
NoSuchMethodError - because of a runtime jar mismatch... its not
pleasant to have this hidden :-)
I have had this very problem in a home-grown Hibernate session filter...
Cheers,
-Nick
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=ick
_______________________________________________
Springframework-developer mailing list
Spr...@li...
https://lists.sourceforge.net/lists/listinfo/springframework-developer
|