If I have an Exception with an @ApplicationException(inherited = true, rollback = true) but I want a subclass to not rollback. Can I just annotate the subclass with @ApplciationException(rollback = false)? Or will that not work? The spec doesn't seem to say, that I could find.
The EJB 3.1 spec (JSR 318) does explain this in section 14.2.1. There is an example:
In the following example :
@ApplicationException(rollback=true)
public class ExceptionA extends RuntimeException
public class ExceptionB extends ExceptionA
@ApplicationException(inherited=false, rollback=false)
public class ExceptionC extends ExceptionB
public class ExceptionD extends ExceptionC
ExceptionA is an application exception with transaction rollback.
ExceptionB is an application exception with transaction rollback.
ExceptionC is an application exception without transaction rollback.
ExceptionD is not an application exception.
JSR 220 does not explicitly state what should happen in this scenario. It does specify that application-exception
deployment descriptor elements will override any annotated value for a specific EJB:
An application exception does not automatically result in marking the transaction for rollback unless the ApplicationException annotation is applied to the exception class and is specified with the rollback element value true or the application-exception deployment descriptor element for the exception specifies the rollback element as true. The rollback subelement of the application-exception deployment descriptor element may be explicitly specified to override the rollback value specified or defaulted by the ApplicationException annotation
This, combined with how annotations work for other Java EE components (@TransactionAttribute
, @ConcurrencyManagement
etc), would lead one to strongly assume that the subclass @ApplicationException
annotation will override that of its parent. I confirmed this to be the case with a simple test (incomplete code shown):
@ApplicationException(inherited = true, rollback = true)
public class MyBaseException extends RuntimeException {
// Constructors
}
public class MySubException1 extends MyBaseException {
// Constructors
}
@ApplicationException(rollback = false)
public class MySubException2 extends MyBaseException {
// Constructors
}
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@Path("/misc/exception")
@Produces(MediaType.APPLICATION_JSON)
public class ExceptionResourceImpl {
@Inject
private BaseDAO baseDAO;
public ExceptionResourceImpl() {
super();
}
@GET
@Path("/app/{id}")
public Response getApplicationException(@PathParam("id") final String id) {
final PaymentTypeModel model = new PaymentTypeModel();
model.setPayment("Key" + System.currentTimeMillis());
if ("1".equals(id)) {
baseDAO.create(model);
throw new MySubException1(
"Throwing sub exception 1, default annotation behaviour");
} else if ("2".equals(id)) {
baseDAO.create(model);
throw new MySubException2(
"Throwing sub exception 2, overrides annotation behaviour");
} else {
return Response.status(Status.BAD_REQUEST)
.entity("Must supply id of 1 or 2").build();
}
}
}
Results:
MySubException2
.* EDIT *
JSR 318 does clarify the behavior of inherited ApplicationException
annotations, through the use of examples.
In the following example :
@ApplicationException(rollback=true) public class ExceptionA extends RuntimeException
public class ExceptionB extends ExceptionA
@ApplicationException(inherited=false, rollback=false) public class ExceptionC extends ExceptionB
public class ExceptionD extends ExceptionC
ExceptionA is an application exception with transaction rollback. ExceptionB is an application exception with transaction rollback. ExceptionC is an application exception without transaction rollback. ExceptionD is not an application exception
This confirms my original statements and testing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With