Тут можно по-разному поступить. Вот, как это делаю я:
Способ 1: название методов get* & find*
User getUserById(Long id) {
return userRepository.getReferenceById(id);
}
Optional<User> findUserById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new NotFoundException());
}
Способ 2 - я вообще из сервисов не возвращаю Optional никогда. Ведь, по сути если вы будете этот слой сервиса использовать в другом сервисе, то скорее всего вам понадобится сама сущность, а не Optional, а если данной сущности нет, то какой смысл дальше его сеттить, а значит нужно выбросить исключение. Обратите внимание, что второй метод возвращает DTO
User findById(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new NotFoundException());
}
UserDTO findUserById(Long id) {
return userMapper.toDTO(findById(Long id));
}
Способ 3: Если не хотите, чтобы исключение выбрасывалось например.
Допустим, у вас первый сервисный слой PostService вызывает второй AuthorService, чтобы выполнить findById и засеттить его значение к записи. Если вы выполните это на уровне сервисов, то исключение будет брошено. Но можно сделать это на уровне мапперов и в случае отсутствия записи засеттить null. Если память не изменяет, такое работает в MapStruct с NullValuePropertyMappingStrategy
Cпособ 4
Создаю 2 метода. Первый возвращает сущность или выбрасывает исключение, а второй возвращает сущность или нулл