|
From: Nick M. <nic...@gm...> - 2005-04-25 02:14:00
|
Chaps,=20
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; =20
171 try {
172 filterChain.doFilter(request, response);
173 }
174
catch (Exception e) {
originalException =3D 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 !=3D 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
|