Spring数据异常处理

时间:2014-01-08 15:42:07

标签: java spring spring-data spring-data-jpa

我正在使用Spring Data-JPA开发一个项目。我需要在JpaRepository方法调用中处理一些异常。

在下面的代码中,我需要拦截主键违规错误,但我无法直接捕获异常。在我的例子中,当发生这种异常时,存储库层(JpaRepository)抛出UnexpectedRollbackException异常。我需要在此异常对象中搜索以确定问题的原因。

我想知道是否有更“优雅”的方法来实现这一目标。

public Phone insert(Phone phone) throws BusinessException {
    Phone result = null;
    try{
        result = phoneRepository.save(phone);
    }
    catch(UnexpectedRollbackException ex){
        if((ex.getCause() != null && ex.getCause() instanceof RollbackException) &&
           (ex.getCause().getCause() != null && ex.getCause().getCause() instanceof PersistenceException) && 
           (ex.getCause().getCause().getCause() != null && ex.getCause().getCause().getCause() instanceof ConstraintViolationException)){
                throw new BusinessException("constraint violation", ex);
        }
    }
    catch(Exception ex){
        throw new OuvidorNegocioException("unknown error", ex);
    }       
    return result;
}

谢谢!

更新

下面的代码似乎要好得多。

public Phone insert(Phone phone) throws BusinessException {
    Phone result = null;
    try{
        result = phoneRepository.save(phone);
    }
    catch(UnexpectedRollbackException ex){
        if(ex.getMostSpecificCause() instanceof SQLIntegrityConstraintViolationException){
                throw new BusinessException("constraint violation", ex);
        }
    }
    catch(Exception ex){
        throw new OuvidorNegocioException("unknown error", ex);
    }       
    return result;
}

2 个答案:

答案 0 :(得分:7)

无论您在何处处理异常,都可以选择查看getMostSpecificCause()的{​​{1}}或getRootCause()方法。 Here is information关于这些方法。

答案 1 :(得分:3)

与评论您的问题的其他人一样 - 我也认为您在帖子中提供的解决方案很糟糕。存储库抽象的唯一目的是隐藏持久性机制,以便客户端不必了解它。在你的情况下,你会寻找一个低级SQL异常,它被Spring以及JPA故意抽象出来。

如果您真的想要处理约束违规,DataIntegrityViolationException是正确的问题。存储库将在Spring DataAccessException子类型中包装特定于商店(MongoDB,JPA,无论您使用什么),以允许客户端完全执行此操作:捕获每个错误类型的异常,而不是每个持久性机制。