On Jun 8, 2009, at 7:07 PM, Martin Probst wrote:
>> By success if you mean the status code is < 500 for success and >=
>> 500
>> otherwise then you can perform that check within the Closeable
>> implementation.
>
> I'm not quite sure about that. Basically in the Java code I want to
> make sure I close that session after the code has executed, and I'd
> like to only commit it if I didn't throw an exception. Come to think
> of it, that might not be a good idea as a WebApplicationException for
> code 304 or similar is not exactly an error, so I might have to
> special-case WAEs. I'll probably have to think about that a bit more
> to find out what exactly constitutes an error in my application.
>
Right.
>> But for Servlet there are cases where the exception may be passed
>> through to
>> the Servlet (if it is not mapped by Jersey), so the status may not
>> be set
>> accordingly unless you have an exception mapper to map all
>> exceptions, or
>> use a servlet filter as you have done.
>
> The not so nice thing about the servlet filter is that you loose all
> the niceties of Jersey (and there are a lot!) once your at that level.
> But an ExceptionMapper<Throwable> will not be called reliably, because
> there might be additional mappers for exception classes that are
> closer to the actual thrown exception, right?
Correct. But as you say not all exceptions necessarily mean an error,
depending on how you application is implemented (and how exceptions
are mapped).
> This doesn't quite meet
> with my requirement of really making sure the transaction handling
> will always work properly.
>
>> I think your idea of allowing a sub-locator method to continue
>> matching
>> within its stack frame is an interesting idea. It should be
>> something that
>> is possible to support, i like the idea of returning a "closure"
>> from which
>> the continue can be performed and wrapped around a try/catch, that
>> way it
>> the "RuleChain" is something that cannot be used in other incorrect
>> scenarios.
>>
>> public Continuation getChild() {
>> final Session session = getSession(...);
>>
>> return new Continuation(new Child(session.get(childName)) {
>> public continue(Continuation next) {
>> try {
>> next.continue();
>> } catch(Exception e) { ... }
>> finally { ... }
>> }
>> }
>> }
>>
>> If this is something you would like to see can you please log a
>> feature/enhancement issue.
>
> See here:
> https://jersey.dev.java.net/issues/show_bug.cgi?id=303
>
Thanks.
> However the code above creates the Child object by accessing the
> session outside of the try/finally, was that intentional?
Yes, for the above example i was assuming that construction and
session.get would not result in an exception. But, i think your
example below is better.
> That
> wouldn't quite work for me: the point is that you want the
> continuation to do all the session related work, so you cannot
> construct the actual return value beforehand.
>
> I'd rather have something like this:
>
> public Continuation getChild() {
> final Session session = getSession(...);
> return new Continuation() {
> public void continue(Chain chain) {
> try {
> Child child = session.get("foo"); // .. or whatever
> chain.continueWith(child);
> session.commit();
> } finally {
> if (session.isOpen()) session.rollback();
> }
> }
> };
> }
>
OK.
> So you basically create a continuation that is responsible for
> yielding the actual sub-locator and passing it to the rule chain,
> which will then continue just as if the method had directly returned
> the child in the first place.
>
> How do the regular EntityManager people handle this?
I am not sure, I am guessing it is if the "method" (Servlet.service or
an EJB method) does not complete (i.e. throws an exception).
Paul.