在将EJBTransactionRolledbackException记录到文件之前捕获它

时间:2016-08-29 08:54:43

标签: java logging jboss ejb

我的设置:

我有一个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)

1 个答案:

答案 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实际上是伪装的锁定异常(也就是说,它是因为另一个用户在此期间修改了某些数据而引发的),可能最好将其报告给用户。