Throwing an application exception causes TransactionalException

萝らか妹 提交于 2020-01-07 05:46:11

问题


I am implementing an JEE7 web application. During my work i have found a problem with handling my custom exceptions.

I edited my account's property to have a non-unique login field. Then i invoked the AccountEditBean#editAccount() to run the editing process. When the process comes to AccountFacade#edit() i can see (in debug) that PersistenceException is caught and my custom NonUniqueException is thrown. The problem is, the exception is not propagated out of the facade class and it is not handled in AccountEditBean. Instead of that TransactionalException occurs right after throw:

WARNING:   EJB5184:A system exception occurred during an invocation on
EJB ADMEndpoint, method: public void
pl.rozart.greatidea.adm.endpoints.ADMEndpoint.editAccount(pl.rozart.greatidea.entities.Account)
throws pl.rozart.greatidea.exceptions.BaseApplicationException
WARNING:   javax.transaction.TransactionalException: Managed bean with
Transactional annotation and TxType of REQUIRES_NEW encountered
exception during commit javax.transaction.RollbackException:
Transaction marked for rollback.

Additional information: NonUniqueException extends BaseApplicationException , which is marked as @ApplicationException(rollback=true).

Here's the code for the edit process:

AccountEditBean:

@Named(value = "accountEditBean")
@ViewScoped
public class AccountEditBean extends UtilityBean implements Serializable {

    @Inject
    ADMEndpointLocal admEndpoint;

    private Account account;

    public void editAccount() {
        try {
            admEndpoint.editAccount(this.account);
            Messages.addInfo(ACCOUNT_DETAILS_FORM, KEY_CHANGES_SUCCESS);
        } catch (NonUniqueException e) {
            Messages.addError(ACCOUNT_DETAILS_FORM, e.getMessage());
        } catch (BaseApplicationException e) {
            Messages.addFatal(ACCOUNT_DETAILS_FORM, e.getMessage());
        }
    }

}

ADMEndpoint:

@Stateful
@Transactional(Transactional.TxType.REQUIRES_NEW)
@TransactionTracker
public class ADMEndpoint extends LoggingStateBean implements ADMEndpointLocal, SessionSynchronization {

    @EJB(name = "ADMAccountFacade")
    private AccountFacadeLocal accountFacade;

    private Account account;

    @Override
    public void editAccount(Account account) throws BaseApplicationException {
        this.account.setLogin(account.getLogin());
        this.account.setEmail(account.getEmail());
        accountFacade.edit(this.account);
    }

}

ADMAccountFacade:

@Stateless(name = "ADMAccountFacade")
@Transactional(Transactional.TxType.MANDATORY)
@TransactionTracker
public class AccountFacade extends AbstractFacade<Account> implements AccountFacadeLocal {

    @PersistenceContext(unitName = "myPU")
    private EntityManager em;

    @Override
    public void edit(Account account) throws BaseApplicationException {
        try {
            em.merge(account);
            em.flush();
        } catch (PersistenceException e){
            if(e.getMessage().contains(Account.CONSTRAINT_ACCOUNT_LOGIN_UNIQUE)){
                throw new NonUniqueException(NonUniqueException.MSG_NON_UNIQUE_ACCOUNT_LOGIN, e);
            }else{
                throw new BaseDatabaseException(BaseDatabaseException.MSG_GENERAL_DATABASE_ERROR, e);
            }
        }
    }
}

Do you know what could be the cause of the problem? It occurs in every of my facades, with all the custom exceptions.


回答1:


I think you should change @Transactional to @TransactionAttribute because EJBs annotated with that. @Transactional is put on managedbean in java 7 not in EJBs...

I copied my comment here because i do not have enough points to squander :)




回答2:


You are throwing an exception from a method whose invocation will be intercepted at runtime and additional logic wrapped around it:

  • transaction management;
  • exception handling.

Your exception cannot transparently jump over that logic, and the specification (probably) says a TransactionalException will be thrown, wrapping your original exception (again, probably---I am not that intimate with the details).



来源:https://stackoverflow.com/questions/21363423/throwing-an-application-exception-causes-transactionalexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!