【问题标题】:Spring JPA Repository Cannot Catch EntityNotFoundExceptionSpring JPA 存储库无法捕获 EntityNotFoundException
【发布时间】:2018-09-21 21:48:51
【问题描述】:

当用户使用无效 ID 搜索我的存储库时,我想抛出一个自定义错误类。这应该非常简单,但我似乎无法捕捉到 JpaRepository 引发的任何错误。我已经多次尝试解决这个问题,但以下是我最直接的尝试:

try {
    Object obj = repository.getOne(id)
}
catch (EntityNotFoundException e) {
    throw CustomException("message");
}

在调试器中运行它时,存储库会抛出我所期望的确切异常 javax.persistence.EntityNotFoundException,但代码只是跳过了我的 catch 语句,并且函数返回错误。

我尝试使用repository.findById(id) 得到类似的结果。我还尝试捕捉ExceptionThrowable。有任何想法吗?如果最终我的问题不是很明显,我会在我的帖子中添加更多信息。

【问题讨论】:

  • 我也遇到了同样的问题!我不明白为什么它会这样,为什么它会跳过捕获:(

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


【解决方案1】:

getOne() 只是EntityManager.getReference() 的包装。该方法不会抛出任何异常。

它返回一个未初始化的代理,假设该实体确实存在。它没有从数据库中获取实体状态,因此甚至不知道它是否存在。它假设确实如此。

如果您尝试访问实体的状态,您以后只会遇到异常。

使用findById()/findOne(),检查是否得到非空/非空结果(因为如果实体不存在,这些方法不会抛出任何异常,它们返回空或空),如果是这样的话,抛出你的异常。

【讨论】:

    【解决方案2】:

    您需要使用@Repository 注解来注解您的存储库类,以执行对特定持久性异常的包装。

    关于问题 - 你不需要使用 getOne() 来处理潜在的异常,但如果实体不存在,你可以使用其他一些方法而不会引发错误,比如 findById() 或另一个返回 Optional 对象的方法

    【讨论】:

    • 这是正确的。我必须用 Optional 来包装我的回复。对 C++ 人来说是违反直觉的。谢谢!
    【解决方案3】:

    你可以捕捉到DataAccessException 而不是EntityNotFoundException

    try {
        Object obj = repository.getOne(id)
    }
    catch (DataAccessException e) {
        throw CustomException("message");
    }
    

    【讨论】:

    • 这不起作用。检查@JB Nizet 的答案。 getOne(id) 在找不到实体时不会立即抛出任何异常。
    【解决方案4】:

    你可以试试这个:

    try {
        Object obj = repository.findById(id).orElseThrow(EntityNotFoundException::new);
    }
    catch (EntityNotFoundException e) {
        throw CustomException("message");
    }
    

    【讨论】:

    • 欢迎来到 SO。尽管我们感谢您的回答,但如果它在其他答案之上提供额外的价值会更好。在这种情况下,您的答案不会提供额外的价值,因为@JB Nizet 已经发布了该解决方案。如果之前的回答对您有帮助,请在您有足够的reputation 时使用vote it up
    猜你喜欢
    • 2014-06-07
    • 2016-01-08
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多