Issue
I have an old web application, running on Tomcat 7, that uses a very rudimentary open-session-in-view mechanism provided by a filter:
@Override public void doFilter (ServletRequest req, ServletResponse resp, FilterChain fc)
throws IOException, ServletException
{
try {
HibernateUtil.beginTransaction();
fc.doFilter(req, resp);
HibernateUtil.commitTransaction();
} catch (Throwable t) {
Logger.exception(t, "processing servlet request");
HibernateUtil.rollbackTransaction();
throw new ServletException(t);
}
}
I'm stuck with this now, and I think I'm running into one of the many flaws with OSIV (or at least this implementation of it) which is that I now want to be able to rollback transactions even without an exception being thrown. I want servlets to be able to control that, and I don't think I have much choice except to hack this functionality on somehow.
My question is: How can I communicate some sort of "rollback" flag from an arbitrary servlet back up to this filter? I want to be able to do something like this in the filter:
HibernateUtil.beginTransaction();
fc.doFilter(req, resp);
if (/* something that was set by a servlet/jsp */)
HibernateUtil.rollbackTransaction();
else
HibernateUtil.commitTransaction();
I'm not really sure what a reliable way to propagate information like that from a servlet back out to this filter is.
Solution
I don't advise using request attributes or thread-local variables, which has the following issues:
- Your transaction is dependent on someone else having set a flag. If you work for a bank, I really don't wanna be a customer there.
- Resource leaking if you don't clean up thread-local storage.
- You can't write multithreaded code without manually copying stuff between thread-local storage.
- If using request attribute, you'll have to extract the value in a Servlet and pass all the way to your DAO, assuming you're using a common multi layered architecture.
Instead, you can simply get the current transaction from the Hibernate session object and ask it to rollback. Session.getTransaction().rollback()
. Best, scrap that code or find the person who wrote it and ask for a refund.
Answered By - Abhijit Sarkar
Answer Checked By - Marilyn (JavaFixing Volunteer)