I'm trying to manage a contended resource (as in: database session) while programming a RESTful web application in Jersey. Usually I'd write code like this:
Session session = getSession();
try {
doWork();
session.commit();
} finally {
session.rollback(); // doesn't hurt after commit
session.release(); // or whatever
}
Now with Jersey, I have a resource like this:
@Path("/")
class MyResource {
@Path("{child}") public Child getChild(...) {
// how do I manage my session here ???
return child;
}
}
The problem is that I need to acquire the session in getChild(), but I cannot make sure I properly release it after work has been done as I've then already given back control to the web application.
Child needs access to the session as well, so I cannot encapsulate all the work in one method:
class Child {
@Path("{subchild}") public Subchild getSubchild(...) {
return new Subchild(session.get(...));
}
}
I cannot wrap the whole application in a servlet Filter as I need information from the Jersey-level to construct my session. Now I could just open it in MyResource, use a regular servlet filter to make sure I always close it, but then I don't know when to rollback and when to commit the session. I could use an ExceptionMapper to be notified of all exceptions, but that would need to be an ExceptionMapper, and this just seems so extremely ugly, with the conceptual try/finally spread over three classes with different lifetimes and so on.
Is there a "right way" to do this kind of resource management in Jersey? How would I make sure I properly close e.g. a FileInputStream after a resource and it's sub-locatos have used it?