无法捕获 EJB 中的异常

Cant catch exception in EJB

我正在 wildfly 8 上使用 Jax-RS 和 EJB3 运行 构建 restful 网络服务。该系统分为两部分。休息模块和持久性模块。其余模块由带有方法的其余 servlet 组成,可在 "mycontext/rest/do" 下访问。此方法调用表示持久性模块接口的无状态 bean 的方法 "do()"。 "do()" 调用另一个无状态 bean 的 "persistEntity(Entity e)",它表示实体 class 的外观(一种接口模式)。我想要保留的实体有一些限制。如果它们被违反,就会抛出像 "ConstraintViolationException" 这样的异常(我认为是 EJB 容器)。我尝试在持久性模块中的两个无状态 bean 之一中捕获异常,但这不起作用。这意味着 catch 块中的代码不会被执行。但是在 servlet 中捕获异常是有效的。

Rest servlet(捕获异常在这里工作):

@Path("/rest")
public class AccountRestService {
    @Inject
    private Service service;
    @POST
    public void do(Entity entity) {
        service.do(entity);
    }
}

代表持久化模块接口的Bean(捕获异常被忽略):

 @Stateless
 @LocalBean
 public class Service {
     @Inject
     private EntityFacade facade;
     public void do(Entity entity) {
         facade.persist(entity);
     }
 }

实体门面(捕获异常被忽略):

@Stateless
public class EntityFacade{
    @PersistenceContext(unitName = "primary")
    private EntityManager em;
    public void create(Entity entity){
        em.persist(entity); // this line throws exception like ConstraintViolationException
    }
}

这是意料之中的。在刷新时抛出异常。刷新发生在事务提交时。提交发生在 EJB 方法成功返回之后。

因此,与您所说的相反,抛出异常的不是 persist() 方法(堆栈跟踪会证实这一点),而是包装您的 EJB 并提交事务的事务代理的方法。

除了

之外,对于这样的异常你真的无能为力
  • 向用户显示错误消息。在那种情况下,在其余服务中捕获异常,或让通用异常处理程序处理它是正确的做法
  • 重试交易。在那种情况下,您应该在其余服务方法和 EJB 之间有一个中间层(或方法),它调用事务性 EJB,捕获异常并重试。