Как заставить методы, сгенерированные spring data jpa, вызывать исключение для нулевых параметров

#java #spring #spring-boot #validation

#java #spring #spring-boot #проверка

Вопрос:

У меня есть этот сервисный метод, который вызывает метод repo, который, в свою очередь, генерируется spring:

Метод обслуживания:

  public User findUserByEmail(String email) {
        try {
            Assert.notNull(email,"email is null!");
            Optional<User> userOptional = userRepo.findUserDAOByEmail(email);
            return userOptional.orElseThrow();
        } 
        catch (...){
            ...
        }
    }
  

Репозиторий:

 public interface UserRepo extends JpaRepository<User, Long> {
    Optional<User> findUserByEmail(String email);
}
  

Я хотел, чтобы метод repo выдавал в IllegalArgumentException качестве своих друзей (методы, которые выходят из коробки с Jparepository do), но вместо этого он принял нулевой параметр «email» и искал его в базе данных и вернул результат, в котором такого пользователя не существует (p.s.: электронная почта ограниченане null в моей схеме)

Так я и сделал Assert.notNull(email,"email is null!");

Но мне интересно, есть ли лучший способ проверить, что «email» не равен null?

Ответ №1:

Ограничение также может быть наложено на параметр следующим образом —

 @Validated
@Repository
public interface UserRepo extends JpaRepository<User, Long> {
    Optional<User> findUserByEmail(@NotNull String email);
}
  

@Validated позволяет Spring вызывать различные ограничения проверки.

Рабочий пример


зависимость от gradle

     compile 'org.springframework.boot:spring-boot-starter'
    compile 'org.springframework.boot:spring-boot-starter-web'
    compile 'org.springframework.boot:spring-boot-starter-validation'
    compile 'org.springframework.boot:spring-boot-starter-data-jpa'
    compile("mysql:mysql-connector-java:8.0.16")
  

UserRepository.java

 @Validated
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
    Optional<User> findUserByName(@NotEmpty String name);
}
  

Вывод на консоль

 javax.validation.ConstraintViolationException: findUserByName.name: must not be empty
    at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:117) ~[spring-context-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at com.sun.proxy.$Proxy88.findUserByName(Unknown Source) ~[na:na]
    at com.test.validation.controller.UserController.get(UserController.java:18) ~[main/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) ~[spring-webmvc-5.2.2.RELEASE.jar:5.2.2.RELEASE]
  

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

1. @User0123 есть ли у вас зависимость spring-boot-starter-validation?

2. @User0123 Это сработало для меня. Есть ли у вас следующая зависимость? mvnrepository.com/artifact/javax.validation/validation-api /.

Ответ №2:

репозитории не имеют возможности получить к нему прямой доступ из классов сервисов, поэтому вам нужно создать класс сервиса с аннотацией @Service, затем реализовать свой собственный метод для поиска пользователя с помощью интерфейса репозитория UserRepo, затем вы можете внедрить класс service в модуль тестирования и выполнить свои собственные тесты.

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

1. Я не думаю, что вы понимаете мой вопрос, чтобы было ясно, что я хочу: если я вызываю findUserByEmail(null) Я хочу, чтобы метод репозитория вызывал исключение IllegalArgumentException

2. вы не можете вызвать исключение IllegalArgumentException непосредственно из репозитория, подробнее о DataAccessException: docs.spring.io/spring-framework/docs/current/javadoc-api/org /…

3. Итак, нет лучшего способа проверить, что параметр не является пустым, если не указано выше? С уровня обслуживания с использованием Assert?

4. в качестве параметра вы можете использовать аннотацию @NotNull, чтобы убедиться, что переданный параметр, аннотированный им, не будет иметь значения null в такой ситуации

5. добавьте этот фрагмент перед возвращением инструкции » if (email == null) { throw new IllegalArgumentException(«Такое электронное письмо не найдено «); } »