Вопрос или проблема
У меня есть репозиторий Spring Boot Data JPA:
@Query(value = """
SELECT .......
""", nativeQuery = true)
ProfileView findByCustomerId(......);
Проекция:
public interface ProfileView {
String getReference();
}
Выполнить запрос:
final ProfileView result = profileRepository.findByCustomerId(......);
final String profile = result.getReference();
Я получаю ошибку:
java.lang.NullPointerException: Cannot invoke "com.ProfileView.getReference()" because "result" is null
У меня пустой результат от SQL-запроса. Знаете, как я могу решить эту проблему? Мне нужно получить просто пустую String profile
без ошибки NPE.
Используйте Optional
@Query(value = """
SELECT .......
""", nativeQuery = true)
Optional<ProfileView> findByCustomerId(......);
Ответ или решение
Как корректно обрабатывать пустые результаты проекции в Spring Boot
При работе с Spring Boot и JPA может возникнуть ситуация, когда при выполнении запроса к базе данных не возвращаются результаты. В данном случае, вы используете проекцию для обработки результата, но столкнулись с ошибкой NullPointerException
. Давайте разберемся, как можно избежать этой ошибки и правильно обрабатывать пустые результаты.
Проблема
Ваша первоначальная реализация репозитория выглядит следующим образом:
@Query(value = """
SELECT .......
""", nativeQuery = true)
ProfileView findByCustomerId(......);
Когда запрос не возвращает результатов, значение переменной result
становится null
, что приводит к NullPointerException
при вызове метода getReference()
:
final ProfileView result = profileRepository.findByCustomerId(......);
final String profile = result.getReference(); // Здесь возникает NPE
Решение
Чтобы избежать ситуации, когда происходит вызов методов на null
, рекомендуется использовать Optional
в качестве возвращаемого типа вашего метода. Это позволит явно указывать, что результат может отсутствовать, и предоставить удобные методы для обработки таких случаев.
Изменение репозитория
Вначале измените метод вашего репозитория, чтобы он возвращал Optional<ProfileView>
:
@Query(value = """
SELECT .......
""", nativeQuery = true)
Optional<ProfileView> findByCustomerId(......);
Обработка результата
Теперь, когда вы вызываете метод, вы сможете безопасно проверять, присутствует ли результат:
final Optional<ProfileView> optionalResult = profileRepository.findByCustomerId(......);
final String profile = optionalResult.map(ProfileView::getReference).orElse("");
В приведенном коде мы используем метод map
для безопасного извлечения значения из Optional
. Если результат существует, будет вызван метод getReference()
, если же нет – будет возвращена пустая строка.
Преимущества использования Optional
-
Упрощение обработки пустых значений: Использование
Optional
позволяет избежать явных проверок наnull
и делает код более читаемым. -
Улучшение безопасности:
Optional
уменьшает риск возникновения краха программы из-заNullPointerException
. -
Четкая семантика: Использование
Optional
делает явным намерение разработчика о том, что результат может отсутствовать, тем самым улучшая понимание кода другими разработчиками.
Заключение
Корректная обработка пустых значений в Spring Boot – это важный аспект разработки, который может значительно упростить ваш код и повысить его надежность. Замена возвращаемого типа метода на Optional
и использование его методов для обработки результата позволит вам избежать ошибок, связанных с null
, и значительно повысит качество вашего приложения.