【问题标题】:How to throw exceptions on search methods in spring data jpa如何在spring data jpa中的搜索方法上抛出异常
【发布时间】:2017-02-12 11:00:35
【问题描述】:

我正在使用 spring-data-jpa 存储库进行数据库操作。如果我的存储库中的所有方法的数据库中不存在对象,我想抛出异常。例如考虑OrderRepository中的以下方法

findByCustomerAndPayment(Customer customer, Payment payment);

我想根据 customerId 和 paymentId 查询所有订单。在上述查询中,这两个对象都是必需的。但是如果我给出的 cutomerId 在数据库中不存在,spring-data-rest 将返回 null。如果数据库中不存在对象,我希望 spring-data-rest 会抛出异常。

如何做到这一点?

【问题讨论】:

  • 您可以将方法前缀从'find'更改为'get',tuhrig.de/find-vs-get
  • 在下面查看@Salah 的解决方案。最佳解决方案。

标签: spring spring-boot spring-data-jpa spring-data-rest


【解决方案1】:

你只需要orElseThrow

orderRepository.findByCustomerAndPayment(customer, payment).orElseThrow(() -> new ResourceNotFoundException("customer", "id", customer.getId()));

【讨论】:

  • 这是我认为最好的解决方案。首先将方法声明为 Optional 然后使用它。谢谢萨拉赫。
  • 我也这么认为,但是,有人知道相反的吗?如果存在则抛出异常?
  • @ghossio 参加聚会有点晚了——你为什么想要它?我现在唯一能想到的就是有一个计数和有条件地抛出异常,但是如果你需要的话,就没有使用 optional
【解决方案2】:

如果您使用的是 Java 8,则可以使用 Optional<Order> 作为存储库方法的返回类型。如果存储库方法返回一个空的Optional,调用get 将抛出一个NoSuchElementException。否则,如果没有结果,则不支持通过存储库方法抛出异常。

try {
  Optional<Order> result = repository.findByCustomerAndPayment(customer,payment);
  Order order = result.get();
} catch(NoSuchElementException e) {
  // do something with the exception
}

【讨论】:

  • 处理 RuntimeExceptions 不应该是一个好方法,特别是如果你可以避免它们。如果元素丢失或存在,可选类有不同的方法来检查和执行操作。示例:order.orElseThrow(...)、order.orElse(...)、order.ifPresent() 等...
【解决方案3】:

您可以像下面这样进行自定义存储库实现:

public interface OrderRepositoryCustom {
    Order findByCustomerAndPaymentRequired(Customer customer, Payment payment);
}

public class OrderRepositoryImpl implements OrderRepositoryCustom {

    @Autowired 
    OrderRepository orderRepository;

    @Override
    public Order findByCustomerAndPaymentRequired(Customer customer, Payment payment) {
        Order o = orderRepository.findByCustomerAndPayment(customer, payment);
        if(o == null) {
            throw new IncorrectResultSizeDataAccessException(1);
        }
        return o;
    }

}

您的OrderRepository 接口应该自定义扩展:

public interface OrderRepository extends CrudRepository<Order, Long>, OrderRepositoryCustom {
    Order findByCustomerAndPayment(Customer customer, Payment payment);
}

已编辑

因为IncorrectResultSizeDataAccessExceptionRuntimeException,所以不需要throws 声明——我已经解决了。

【讨论】:

    【解决方案4】:

    OptionalorElseThrow 一起使用。

    Order findByCustomerAndPayment(Customer customer, Payment payment);
    
    default Order findByCustomerAndPaymentOrThrow(Customer customer, Payment payment) {
        return Optional.ofNullable(findByCustomerAndPayment(customer, payment)).orElseThrow();
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      • 2013-11-13
      • 2016-08-09
      • 2023-03-13
      • 2018-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多