The container will not rollback the transaction if an application exception is thrown as it is assumed that the client expects that exception (can recover from it). As an application exception is a checked exception, check what you are throwing. Could it be SQLException? If so, you probably won't want to throw this, in which case you should wrap it in EJBException and throw EJBException.
If you do throw an application exception but decide that it makes no sense to continue with the transaction, then you must first invoke setRollbackOnly() followed by the throwing of that application exception. setRollbackOnly() will force the container to rollback the transaction.
The exception is a business exception, and I have to throw it as a business exception rather than throwing as EJBException. Could this be solved by marking the transaction for rollback in the catch block of the business exception in the session bean and rethrowing the same ??
What you would like to consider is to let your exception to subclass from a runtime exception. Then the rollback will kick in.
This would be correct if the bean must throw a system exception, thus forcing the container to rollback the transaction.
But harsha refers to a business exception being thrown, so it is reasonable to believe that this is an application exception which the container will always propagate to the client without a transaction rollback. But sometimes it is right to abandon a transaction even when an application exception is thrown, which is why I said that the setRollbackOnly() method must be invoked before throwing the application exception.
right on target !! marking the transaction for rollback did the trick !
But any particular reason why, an application exception does not qualify for a roll back implicitly? . Business exceptions are excpected by the client , but most of the cases , this sort of an exception ,might occur in the middle of a transaction , which should be rolled back. Could the container be told to roll back for all exceptions , any settings that could be done?
I have to ask what sort of business exceptions should be rolled back "most of the cases" as business exceptions should normally be handled by the client. Are these actually system exceptions? If so, then you should be throwing system exceptions. You will usually do this by:
- ducking any RuntimeException (or subclasses thereof), thus making the container handle the exception (write a log entry, rollback, kill the bean instance, send RemoteException or EJBException to a remote or local client respectively)
- catching an exception, eg SQLException, turn it into a system exception by wrapping it in and throwing an EJBException (which causes the same actions as above as EJBException IS-A RuntimeException).
- invoking setRollbackOnly().
So, you will only get a container-managed rollback for a CMT bean if it throws a system exception or invokes setRollbackOnly().