使用JPA + Hibernate进行异常处理

Fri*_*itz 5 hibernate jpa-2.0

我正在使用JPA和Hibernate作为容器管理事务的提供者(JBoss AS 6.1.0.Final).

我正在尝试实现一些细粒度的异常处理,因为我的应用程序上有一个特殊的异常层次结构,所以我可以定义在每种情况下要做什么.所以,我一直在调查几个小时,我发现文档含糊不清,示例有点原始,因为异常处理总是"为了清晰"而省略,或者是一个处理Exception e的简单try-catch块.

例如,请使用以下代码:

public void deleteCompany(ICompany company) throws MyException1, MyException2 {
    if(entityManager != null){
        if(company !=null) {
            try {
                ICompany companyReference= entityManager.getReference(Company.class, company.getId());
                entityManager.remove(managedCompany);
                entityManager.flush();
            } catch(EntityNotFoundException companyDoesNotExist) {
                //Wrap & Throw
            }
        } else {
        throw new MyException1("An error occurred while attempting to save a null instance of a company");
        }
    } else {
        throw new MyException2("The entity manager instance is null");
    }   
}
Run Code Online (Sandbox Code Playgroud)

catch块是空白的,因为那是我被卡住的地方......我不知道应该捕获哪个异常来警告系统用户试图删除不存在的记录.

我的具体问题是:我可以在catch块上捕获Hibernate异常,还是必须捕获JPA异常?我发现一些消息来源声称JPA包含了提供商的例外,但这听起来很奇怪.我还发现调用flush()方法可以捕获数据库访问和操作异常,因为事务由容器管理,因此在调用deleteCompany之后会进一步执行约定.

谢谢.

编辑:我正在用我自己用@ApplicationException(rollback = true)注释的异常包装我捕获的异常,所以我可以再次抛出它们并更清楚地处理它们.

编辑2:我已经更新了我的代码.删除之前的合并会在公司不在数据库中时持续存在,从而导致删除每次都成功.现在异常被抛出,我正在测试它在不同情况下如何捕获Perception建议的JPA异常.

编辑3:现在它正在工作!由于该合并调用,结果错误部分在我的代码中.首先获取引用并尝试删除后的技巧,这样我就能捕获EntityNotFoundException,将其包装并再次抛出.

Per*_*ion 5

您肯定不会捕获供应商异常,因为它们会被归入JPA异常.请注意,您可能会在相关位置获得以下几种异常类型之一:

  • IllegalArgumentException - 用于分离或非实体对象
  • IllegalStateException - 实体经理已经关闭
  • PersistenceException - 至少,它的一些子类.如果没有关联的事务并且调用需要一个,如果数据库约束拒绝操作,事务花费太长等等,您可以出于多种原因获取此信息.

除非您计划将它们重新包装在某种自定义应用程序异常中,否则您确实不应该在如此低的级别捕获这些异常.如果您决定转到该路由,请确保包装原始异常,以便堆栈跟踪不会丢失.

值得注意的是,JPA实体管理器生成的所有异常都是运行时异常.