In this piece of code the task is to override system exceptions (JPA, JTA exceptions) with application exceptions:
transaction.begin();
bm(); //business method
} catch (PersistenceException) {
//rewrite persistence exception and throw it (1)
} finally {
try {
transaction.commit();
} catch (RollbackException re) {
if( re.getCause() instanceof PersistenceException ) rewrite
else // THROW SOME DEFAULT EXCEPTION (2)
}
}
The rewriting of PersistenceException (PE) is straightforward.
It could come from the business method (bm()) and from commit().
When it comes from commit() it is wrapped in RollbackException. Thus the if.
Unfortunately if PE is raised from the bm(), it is also raised from the commit().
So if I throw an exception at (1), it gets overridden in (2). As simple as that. Because of the finally's ability to override results (OOP got messy here).
So what should be fixed?
First, at (2) I shouldn't throw any exception.
Second, I'm thinking of checking the result of bm() - if an exception, don't call commit(), but rollback().
Sounds right.