#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();
};