I am unclear on exactly what the JPA specification says should happen if ManagedType#getSingularAttribute(String) throws an IllegalArgumentException. It seems to be very careful to spell out exactly those cases where any existing transaction should be rolled back, and this state of affairs does not seem to be among them. (Those states of affairs are most commonly EntityManager operations.) My default position therefore is that no transaction rollback should occur. Is this correct?
(For completeness, if you are in one of the states of affairs listed in the JPA specification, then the mere throwing of (for example) a RuntimeException is what marks the transaction for rollback. Catching and ignoring it does not let you off the hook.)
So we're home free, right?
Not so fast, although maybe. As with most people, I'm using JPA inside a stateless session bean.
The EJB 3.1 specification's Table 16 says (interpreted and paraphrased) that if a business method encounters a system exception, then the transaction rolls back. It suggests that this happens at container catch time (i.e. only if the container sees the system exception in question—implying, but not stating explicitly, that if you catch it beforehand and deal with it it is as though nothing happened. Contrast this with the "throws" time rollback in the JPA specification).
So if I'm in an (EJB 3.1) stateless session bean, in a JTA transaction, and I do this:
boolean attributeExists = true;
try {
jpaManagedType.getSingularAttribute(attributeName, attributeJavaType);
} catch (final IllegalArgumentException noSuchAttribute) {
attributeExists = false;
}
...should my JTA transaction still be committable? Or is it required to be rolled back at IllegalArgumentException "throws" time?