我的设置:
我有一个EJB bean(在JBoss 6.4的耳边部署),它有一个计算某些值并将其存储在数据库中的方法。该方法在新事务中启动。它看起来像这样:
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void doStuff() {
MyObject value = calculateSomeValues();
entityManager.merge(value);
entitiyManager.flush();
}
按照设计,由于ConstraintViolationException
,刷新可能会失败。由于这是一个新事务,该异常将包含在EJBTransactionRolledbackException
中并作为RuntimeException
抛出。我已经为ejb异常设置了日志记录,因为在整个系统中查找它们很有用。但是,我知道ConstraintViolationException会偶尔发生,我想在日志系统将其记录为错误之前捕获它并回滚(约束违规不被视为异常,但是从数据库的角度来看它是必需的视图)。目前,我的日志文件被这样的条目堵塞:
ERROR [org.jboss.as.ejb3.invocation] (default-threads - 49) JBAS014134: EJB Invocation failed on component
如何以阻止记录器打印这些错误的方式捕获异常? (注意:我仍然希望它记录所有其他EJBTransactionRolledbackException
s)
答案 0 :(得分:1)
我没有部署JBoss 6,所以我无法立即测试精确的异常类型是否也适用于JBoss 6(我在WildFly 8上试过这个)。
一种可能的解决方案是在您的EJB中添加一个@AroundInvoke注释的方法(至少如果您在此EJB上没有其他拦截器):
@AroundInvoke
public Object myConstraintViolationInterceptor(InvocationContext ctx) throws Exception
{
try {
return ctx.proceed();
}
catch(PersistenceException e) {
if (e.getCause() instanceof org.hibernate.exception.ConstraintViolationException) {
//some action taken
}
else {
throw e;
}
return null;
}
}
顺便说一下,如果您的ConstraintViolationException实际上是伪装的锁定异常(也就是说,它是因为另一个用户在此期间修改了某些数据而引发的),可能最好将其报告给用户。