users@glassfish.java.net

Re: Unexpected Behavior: NoResultException rolls back transaction

From: <glassfish_at_javadesktop.org>
Date: Fri, 25 Jan 2008 09:45:38 PST

Hi,
Chris is actually right, but also let me try to clarify this a little bit:)

NoResultException is a runtime exception, you do not have to catch it...If you do catch it and handle it, (and do not rethrow it at the last statement of your method!),
then of course as the API javadoc suggests, it will not cause the transaction to rollback.


However, try this:
Try to throw a different runtime exception yourself from doAnything, for example, the code below throws an ArithmeticException:


@Stateless
public class YBean implements YBeanLocal {
@PersistenceContext
private EntityManager em;

public AnEntity doAnything(String value) throws ArithmeticException {
try {
Query query = em.createNamedQuery("SomeQuery");
query.setParameter("aParam", value);
return (AnEntity) query.getSingleResult();
} catch (NoResultException nre) {
throw new ArithmeticException();
}
}

I bet you, you will not be able to catch that ArithmeticException from any Bean that calls YBean.doAnything().... This being a CMT, the container realises that
a runtime exception was thrown, (that apparently, noone would be bothered to catch) and goes: "Hey, there was a runtime exception, I will rollback the transaction
and I will throw a TransactionRolledBack Exception".

*javadoc correctly mentions that the transaction is not rolledback because of NoResultException*... Think of this code:

public AnEntity doAnything(String value) {

//perform an update:
manager.merge(someObject);
try
{
//perform a select query which let's assume causes a RUNTIME exception of NoResultException, after catching this, the code simply continues....
Query query1 = em.createNamedQuery("SomeQuery");
query1.setParameter("aParam", value);
SomeResult result1 = query1.getSingleResult();
}catch(NoResultException e)
{
   //hey, there was an error....
}
//perform another update
manager.remove(anotherObject)
}// at this point someObject has been updated in the db, and anotherObject has been removed from the DB, and the transaction never rolled back....



>Do you mean that if "doAnything()" did not catch NoResultException AND did not rethrow NoResultException AND a NoResultException occured in "doAnything()" the transaction would not be rolled back?

No, I do not think that's what he meant...
if the runtime exception was not caught in doAnything, (as it is now!) the Container would intervene at the end of the method: It would rollback the db due to runtime exceptions, and it would then throw a TransactionRolledBackException.

But it is *not* specifically the NoResultException that would cause this, even an un-cought ArithmeticException would cause the transaction to rollback.

That's what i think anyway:)
[Message sent by forum member 'mmichalak' (mmichalak)]

http://forums.java.net/jive/thread.jspa?messageID=255821