when a stateless session bean method throws a system-exception, the transaction will be rolled back. But when I catch the system-exception and rethrow an application-exception to the client, will the transaction still be rolled back?
The rollback depends on how you define your application exception. If you are using EJB 3.0, you have provision to set rollback=true or false using annotation @Application Exception.
If the rollback is set to true for your application, then the Transaction will rollback.
The following is an excerpt from the book "Pro EJB 3". I like this book very much, but the following example is one of the few things that I have problems to understand:
The book says:
"The ChangeCollisionException class is annotated with @ApplicationException, which is an EJB 3.0 containter annotation in the javax.ejb package to indicate to the container that the exception is not really a system-level exception but should be thrown back to the client as is. Normally, defining an application exception will cause the container to not roll back the transaction, but this is an EJB 3.0 container notion. The persistence provider that threw OptimisticLockException does not know about the special semantics of designated application exceptions and seeing a runtime exception will go ahead and mark the transaction for rollback."
And the spec says:
" 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."
In the above example the ApplicationException annotation has no rollback element set to true. I do not understand why "throw new ChangeCollisionException()" causes the transaction to roll back.
In the above example the ApplicationException annotation has no rollback element set to true. I do not understand why "throw new ChangeCollisionException()" causes the transaction to roll back.
It doesn't rollback the transaction. The text you posted doesn't say the transaction is rolled back.
But it says that the persistence provider will mark the transaction for rollback:
Normally, defining an application exception will cause the container to not roll back the transaction, but this is an EJB 3.0 container notion. The persistence provider that threw OptimisticLockException does not know about the special semantics of designated application exceptions and seeing a runtime exception will go ahead and mark the transaction for rollback
Duran Harris wrote:But it says that the persistence provider will mark the transaction for rollback:
Normally, defining an application exception will cause the container to not roll back the transaction, but this is an EJB 3.0 container notion. The persistence provider that threw OptimisticLockException does not know about the special semantics of designated application exceptions and seeing a runtime exception will go ahead and mark the transaction for rollback
Because OptimisticLockException is not marked as a @ApplicationException. It's the ChangeCollisionException which is marked as an @ApplicationException. That's the reason why the OptimisticLockException is being explicitly caught by the bean and converted to a ChangeCollisionException, to avoid the rollback from happening.