【发布时间】:2014-02-17 06:17:45
【问题描述】:
我正在实现一个 JEE7 Web 应用程序。在我的工作中,我发现处理我的自定义异常有问题。
我编辑了我帐户的属性,使其具有非唯一的登录字段。然后我调用AccountEditBean#editAccount() 来运行编辑过程。当进程来到AccountFacade#edit() 时,我可以看到(在调试中)PersistenceException 被捕获并且我的自定义NonUniqueException 被抛出。问题是,异常没有传播到外观类之外,也没有在AccountEditBean 中处理。而不是TransactionalException 出现在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.
附加信息:
NonUniqueException 扩展 BaseApplicationException ,标记为 @ApplicationException(rollback=true)。
这是编辑过程的代码:
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());
}
}
}
ADM端点:
@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);
}
}
}
}
您知道问题的原因是什么吗?它出现在我的每一个立面中,除了所有自定义例外。
【问题讨论】:
-
ADMEndpoint类的editAccount方法中没有account字段怎么调用accountFacade.edit(this.account)?
-
对不起,我只是没有把它贴在这里。现在应该很清楚了。 :)
-
那么Account参数在editAccount方法中是没有用的,因为你从来没有使用过!
-
我希望现在一切都清楚了。 :)
-
我认为您应该将
@Transactional更改为@TransactionAttribute,因为带有注释的 EJB。@Transactional在 java 7 中的 managedbean 上而不是在 EJB 中...
标签: java jakarta-ee jpa exception-handling transactions