0
votes

I have the following code:

        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public Car prepareCar(Data data) throws CarServiceException{
          Car car = null;
          try {
            car = carManagerBean.createCar(data);
            Driver driver = createDriver();
            car.setDriver(driver);
          } catch (Exception e) {
            LOGGER.error(e.getMessage, e);
            context.setRollbackOnly();
            throw new CarServiceException(e);
          }
          return car;
         }

The problem is that if some problems appear in try section (e.g. SQLServerException) catch section is not executed and CarServiceException is not thrown. Does anybody know what might be the problem with this code? But the transaction is rolled back anyway. It works only if I move try-catch block to wrap the method call.

2

2 Answers

1
votes

You want to catch the exception outside the transaction. Do this:

@Stateless
public class CarServiceDelegate {

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
   public Car prepareCar(Data data) throws CarServiceException{
      Car car = carManagerBean.createCar(data);
      Driver driver = createDriver();
      car.setDriver(driver);
      return car;
   }
}

public class CarService {

   @EJB
   private CarServiceDelegate carServiceDelegate;

   public Car prepareCar(Data data) {
       try {
           return carServiceDelegate.prepareCar();
       } catch (Exception e) {
        // You will catch it here, when the transaction is done.
        LOGGER.error(e.getMessage, e);
        throw new CarServiceException(e);
      }
   }

}

I will give you an update as to which part of the EJb exception mandates the propagation of the Exception outside the transaction. Similar behaviour happens (where the exception is suppressed) in an @Asynchronous invocation.

0
votes

Remember that if your catch block itself throws an exception, it will not get to the segment that rethrows the exception. Note that according to the documentation, setRollbackOnly() can throw an IllegalStateException if the transaction is no longer active. You might want to wrap the catch block within another try/catch block to discover that.