CDI TransactionInterceptor

时间:2015-11-15 14:28:37

标签: java hibernate jpa cdi

如何捕获拦截器CDI的返回?

我创造了这个:

@Interceptor
@Transactional
public class TransactionInterceptor implements Serializable {

    private static final long serialVersionUID = 1L;

    private @Inject EntityManager manager;

    @AroundInvoke
    public Object invoke(InvocationContext context) throws Exception {

        System.out.println("Interceptor on!");      
        EntityTransaction trx = manager.getTransaction();
        Object obj = null;
        boolean criador = false;

        try {

            if (!trx.isActive()) {

                System.out.println("Iniciando transação ...");
                trx.begin();

                criador = true;
            }

            obj = context.proceed();

            if (trx != null && trx.isActive() && criador) {

                System.out.println("Comitando ...");
                trx.commit();

            }

            System.out.println("Finalizando interceptor ...");

        } catch (Exception e) {

            System.out.println("ERRO ENCONTRADO !");
            System.out.println(e.getMessage());

            if (trx != null && trx.isActive() && criador) {
                System.out.println("Rollback ...");
                trx.rollback();
            }

            System.out.println("Finalizando interceptor ...");

            return obj;
        } 

        return obj;
    }

}

我想知道事务是提交还是回滚。

这是主要方法:

@Override
@Transactional
public boolean salvar(Funcionario funcionario) {

    return funcionarioDAOImpl.salvar(funcionario);
}

我该怎么做?我不用春天。

2 个答案:

答案 0 :(得分:0)

不确定你要做什么。截获的方法并不知道它被截获,并且没有"拦截器的返回(值?)"。

在Java EE 7中,有d1$market<-as.character(d1$market) d2$metro<-as.character(d2$metro) find<-function(x){fn$sqldf("select market from d1 where market like '%$x%'")} p<-d2$metro m<-lapply(p,function(y) find(y)) data.frame(matrix(unlist(m))) 1 Some place in Chicago 2 New York, NY 拦截器绑定,它开箱即用。无需为JPA事务编写自己的拦截器。

答案 1 :(得分:0)

如何找到答案的最简单方法是在回滚事务后从拦截器中抛出RuntimeException。这正是标准Java EE 7 @Transactional注释所做的 - 如果一切正常,事务被提交并且正常执行继续,或者事务被回滚并且调用代码需要捕获异常。

代码示例:

@Interceptor
@Transactional
public class TransactionInterceptor implements Serializable {

    @AroundInvoke
    public Object invoke(InvocationContext context) throws Exception {
        ...
        try {
          ...
        } catch (Exception e) {

            if (trx != null && trx.isActive() && criador) {
                trx.rollback();
                throw new RuntimeException("Transaction rolled back!", e);
            }

        } 

        return obj;
    }

}

// transactional bean
public class SalvarExecutor {
@Transactional
public boolean salvar(Funcionario funcionario) {
   return funcionarioDAOImpl.salvar(funcionario);
}
}

// caller CDI bean
public class Caller {
  @Inject SalvarExecutor executor;

  public void execute() {
    try {
      salvar.salvar();
    } catch (Exception e) {
      // salvar was rolled back by the interceptor
    }
  }
}

您可以在catch块中引入自己的RuntimeException后代。

另一种选择,虽然不那么干净和可读:

可以创建一个单独的@RequestScoped bean,您可以将其注入拦截器和调用者bean。然后拦截器可以间接与调用者通信 - 它可以更新中间请求作用域bean,然后调用者可以从同一个bean中检索数据。