user1645419
user1645419

Reputation: 217

EJB 3.1 transactions rollback doesn't work

i have the following scenario:

i have a stateless ejb with two method A() and B(). The method B() perform n call to method A() which execute an INSERT operation. Now, if A() throws an applicationException ( that i have annotated with @javax.ejb.ApplicationException(rollback=true) ) and i catch this exception in a catch block of method B(), this doesn't rollback my transaction e so the INSERT is executed:

public void A() throws ApplicationException {

.....//some logic here

doInsert(); //entity layer method that perform the insert operation

throw new ApplicationException(); // this is only for test

}

this is method B():

public void B() {

try{

   A(); //this method is called n time in a loop but it doesn't matter

} catch (ApplicationException e){

e.printStackTrace();

}

This is the applicationException:

@javax.ejb.ApplicationException(rollback=true) public class ApplicationException extends Exception {

public ApplicationException() {

   super();

}

}

Obviously, this behavior does not occur if i remove the catch block in the method B(). Now, i'm wonder if there's a way to rollback my transaction even if i catch the exception in the method B(). Thankss!!!!

Upvotes: 0

Views: 1019

Answers (2)

Xinsheng Huang
Xinsheng Huang

Reputation: 11

To make the code work, B() has to go through lookup process to get another instance of the ejb, and call A() on that instance. That way the container has chance to "see" the exception A() throws.

Upvotes: 1

Brett Kail
Brett Kail

Reputation: 33936

Per section 14.2.1 of the EJB 3.1 specification:

Application exceptions that are checked exceptions may be defined as such by being listed in the throws clauses of the methods of the bean’s businessinterface, no-interface view, home interface, component interface, and web service endpoint. An application exception that is an unchecked exception is defined as an application exception by annotating it with the ApplicationException metadata annotation, or denoting it in the deployment descriptor with the application-exception element.

Your exception class extends Exception, so it is a checked exception, so the @ApplicationException annotation is ignored. If you want to rollback the exception when throwing this exception, you should use EJBContext.setRollbackOnly after catching the exception in A (it could also be done before throwing the exception, but doing it from the catch block is probably a better style since it emphasizes "handling" the exception). Alternatively, you could change the exception to extend RuntimeException, but you might not want to do that depending on how you feel about unchecked exceptions.

Upvotes: 1

Related Questions