У меня есть следующий метод
private Invoice createInvoice(SomeParameter someParameter) {
Invoice invoice = new Invoice();
Optional<Customer> customer = customerRepository.findByCode(someParameter.getCustomerCode());
invoice.Customer(resource.get());
return this.createInvoice(...);
}
Я ищу клиента, который будет назначен счету-фактуре. Нет никаких шансов, что код клиента в параметре не существует в БД.
В любом случае, я знаю, что напрямую вызывать метод get() для необязательных значений — плохая практика, но все же я не хочу проверять, присутствует ли значение, это выглядит как какой-то шаблонный код. Есть и другие поля, такие как клиент, которые являются необязательными.
Есть ли лучший способ справиться с необязательным здесь?
Что такое resource? Этот метод должен быть бесконечно рекурсивным или this.createInvoice(...) вызывает перегрузку? Должен ли invoice.Customer(resource.get()); создавать объект Customer (потому что, если это так, вы просто его выбрасываете) или он вызывает метод (в этом случае вы должны использовать стандартные соглашения об именах Java и назвать метод customer)?
Один из способов избежать .get() — использовать customer.map().orElseThrow(), а затем обработать исключение и, возможно, сопоставить с записью Invoice. В любом случае вам все равно нужно получить значение необязательного




There is no chance that the customer code in the parameter does not exist in the DB.
Если вы уверены, что результат присутствует в полученном вами необязательном объекте, то вместо get() вы должны вызвать orElseThrow(), который делает то же самое - извлекает значение (если имеется), но, в отличие от get(), явно показывает ваше намерение бросить NoSuchElementException, если необязательный объект не содержит результата.
У этого метода есть перегруженная версия, которая ожидает поставщика типа Throwable и позволяет предоставить желаемый тип исключения для случая пустого опционала.
Если вы не хотите обрабатывать необязательный параметр, не возвращайте его из метода репозитория, просто верните объект Customer. Вы также можете аннотируйте свой метод репозитория с @Nullable, если это необходимо.
interface CustomerRepository extends Repository<Customer, Long> {
Customer findByCode(...);
// or
@Nullable
Customer findByCode(...);
}
private Invoice createInvoice(SomeParameter someParameter) {
Invoice invoice = new Invoice();
Optional<Customer> customer = customerRepository.findByCode(someParameter.getCustomerCode());
//1.invoice.Customer(resource.orElse(null));
//2.resource.ifPresent(res->invoice.Customer(res));
//3.invoice.Customer(resource.orElseThrow(()->new Exception("xxx")));
return this.createInvoice(...);
}
Что вы хотите
Совсем без шансов? Что, если бы кто-то сделал
someParameter.setCustomerCode(random.nextInt(9000))?