Как создавать исключения для методов поиска в spring data jpa

#spring #spring-boot #spring-data-jpa #spring-data-rest

#spring #spring-boot #spring-data-jpa #spring-data-rest

Вопрос:

Я использую репозитории spring-data-jpa для операций с базой данных. Я хочу создавать исключения, если объект не существует в базе данных для всех методов в моих репозиториях. Например, рассмотрим следующий метод в OrderRepository

 findByCustomerAndPayment(Customer customer, Payment payment);
  

Я хочу запрашивать все заказы на основе CustomerID и PaymentID. Оба объекта необходимы в приведенном выше запросе. Но spring-data-rest возвращает null, если я указал, что cutomerId не существует в базе данных. Я ожидаю, что spring-data-rest выдаст исключение, если объект не существует в базе данных.

Как этого добиться?

Комментарии:

1. Вы можете изменить префикс метода с ‘find’ на ‘get’, tuhrig.de/find-vs-get

2. Проверьте решение @Salah ниже. Лучшее решение.

Ответ №1:

Вам просто нужен orElseThrow

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

Комментарии:

1. Я думаю, это лучшее решение. Сначала разработайте метод как необязательный<{Type}>, а затем используйте это. Спасибо Салах.

2. Я думаю то же самое, но кто-нибудь знает обратное? Выбрасывать исключение, если оно существует?

3. @ghossio немного опоздал на вечеринку — зачем вам это нужно? единственное, о чем я могу думать прямо сейчас, — это подсчет и условное исключение, но необязательный параметр не используется, если это то, что вам нужно

Ответ №2:

Если вы используете Java 8, вы можете использовать Optional<Order> в качестве возвращаемого типа метода репозитория. Если метод репозитория возвращает пустое Optional значение, вызывающее get, он выдаст a NoSuchElementException . В противном случае нет поддержки для создания исключений методами репозитория, если нет результатов.

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

Комментарии:

1. Обработка исключений 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);
}
  

Отредактировано

Как IncorrectResultSizeDataAccessException есть RuntimeException , тогда нет необходимости throws объявлять — я это исправил.

Ответ №4:

Используйте Optional вместе с orElseThrow .

 Order findByCustomerAndPayment(Customer customer, Payment payment);

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