简体   繁体   English

Spring数据异常处理

[英]Spring Data Exception Handling

I´m working on a project using Spring Data-JPA. 我正在使用Spring Data-JPA开发一个项目。 I need to handle some exceptions in JpaRepository method calls. 我需要在JpaRepository方法调用中处理一些异常。

In the code bellow, I need to intercept primary key violations erros but I cannot catch the exception directly. 在下面的代码中,我需要拦截主键违规错误,但我无法直接捕获异常。 In my case, when an exception of this kind occurs, the UnexpectedRollbackException exception is thrown by repository layer (JpaRepository). 在我的例子中,当发生这种异常时,存储库层(JpaRepository)抛出UnexpectedRollbackException异常。 I need to search inside this exception object to determine what is the cause of the problem. 我需要在此异常对象内搜索以确定问题的原因。

I am wondering if there is a more "elegant" way to achieve this. 我想知道是否有更“优雅”的方式来实现这一目标。

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;
}

Thanks! 谢谢!

UPDATE: 更新:

The code bellow seems to be much better. 下面的代码似乎要好得多。

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;
}

Wherever you handle the exception, you have the option of looking into the getMostSpecificCause() or getRootCause() methods of UnexpectedRollbackException . 无论你在哪里处理异常,你必须寻找到的选项getMostSpecificCause()getRootCause()方法UnexpectedRollbackException Here is information about those methods. 以下是有关这些方法的信息

As with others who have commented on your question — I, too, think the solution you have in your post is a bad one. 与评论您的问题的其他人一样 - 我也认为您在帖子中的解决方案很糟糕。 The sole purpose of a repository abstraction is to hide away the persistence mechanism so that clients don't have to know about it. 存储库抽象的唯一目的是隐藏持久性机制,以便客户端不必了解它。 In your case you look for a low-level SQL Exception which has been intentionally abstracted away by Spring as well as JPA. 在你的情况下,你寻找一个低级SQL异常,它被Spring和JPA有意地抽象出来。

If you really want to handle a constraint violation, the DataIntegrityViolationException is the correct one to catch. 如果您确实想要处理约束违规, DataIntegrityViolationException是要捕获的正确的。 The repositories will wrap the store specific (MongoDB, JPA, whatever you use) in Spring DataAccessException subtypes to allow the clients to do exactly that: catch an exception per error type, not per persistence mechanism. 存储库将在Spring DataAccessException子类型中包装特定于商店(MongoDB,JPA,无论您使用什么),以允许客户端完全执行此操作:捕获每个错误类型的异常,而不是每个持久性机制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM