【问题标题】:Hibernate validation - autowired returns null休眠验证 - 自动装配返回 null
【发布时间】:2020-08-06 10:19:17
【问题描述】:

环顾四周,我找不到任何好的解决方案。

我的 autowired 没有按预期工作,它返回 null。我已经在其他类中自动装配了这个特定的类,它可以工作,所以它只在约束验证器类中不起作用。

用户服务类

@Service
public class UserService {

    @Autowired
    private UserRepository userRep;
    
    public void addUser(User user) {
        userRep.save(user);
    }
    
    
    public void deleteUser(long userId) {
        userRep.deleteById(userId);
    }
    
    public List<User> retrieveAllUsers(){
        Iterable<User>temp =userRep.findAll();
        List<User>allUsers = null;
        temp.forEach(allUsers::add);
        return allUsers;
    }
    
    public boolean searchByEmail(String email) {
        return userRep.findByEmail(email);
    }
    
    public void updateUser(User user) {
        userRep.save(user);
    }
}

注解接口类

 @Target(ElementType.FIELD) 
    //When will the annotation be processed compilation, runtime etc
    @Retention(RetentionPolicy.RUNTIME)
    //Where is the logic
    @Constraint(validatedBy = EmailValidator.class)
    @Documented
    public @interface ValidEmail {
        
        //Error message
        String message() default "Invalid email";
        //Required for annotation
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};
        
    }

注解逻辑类。这里的 autowired 返回 null

public class EmailValidator implements ConstraintValidator<ValidEmail, String> {

    @Autowired
    private UserService service;
    //Actual place to place the logic to check if the data is valid or not
    @Override
    public boolean isValid(String email, ConstraintValidatorContext context) {
        if (email == null) {
        return false;
        }
        
        List<User> users = service.retrieveAllUsers();
        if (users.size() > 0) { 
        return Pattern.matches("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])", email)
                && service.searchByEmail(email);
        }
        
        else {
            return Pattern.matches("(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])", email);
        }
        }
        
    
    
    @Override
    public void initialize(ValidEmail validEmail) {
        validEmail.message();
    }

}

主要

@SpringBootApplication
@ComponentScan(basePackages = {
        "com.Alex.Mains", "com.Alex.UserPackage", "com.Alex.Flights", "com.Alex.Security"
})
@EntityScan( basePackages = {"com.Alex.UserPackage", "com.Alex.Flights"})
@EnableJpaRepositories({"com.Alex.UserPackage", "com.Alex.Flights"})
public class JpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(JpaApplication.class, args);
    }
    
//  @Bean
//  public Validator validator(final AutowireCapableBeanFactory beanFactory) {
//
//      ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
//              .configure()
//              .constraintValidatorFactory(new SpringConstraintValidatorFactory(beanFactory))
//              .buildValidatorFactory();
//
//      return validatorFactory.getValidator();
//  }
    
}

编辑:尝试@Componenet

【问题讨论】:

    标签: spring spring-boot hibernate spring-mvc hibernate-validator


    【解决方案1】:

    编辑:我的建议

    使用现有的@EMail 和唯一约束代替自定义验证器:

    @Entity
    public class User {
      // ...your properties
    
      @Email
      @Column(unique = true)
      private String email.
    
      // Rest of class...
    }
    

    旧:

    所以,首先:

    List<User> users = service.retrieveAllUsers();
        if (users.size() > 0) { 
    

    您正在从数据库中获取所有用户,只是为了检查是否存在任何用户?这是非常非常低效的。如果您已经在使用 Spring Data,您可以这样做

    @Query("SELECT COUNT(*) > 0 FROM Users")
    boolean anyExists();
    

    此外,您的 Service 不会被注入,因为 EmailValidator 是 POJO(普通的旧 java 对象)而不是 Spring 托管组件。如果你用@Component@Service 注释它,Spring 会处理注入。

    但我不建议这样做。我不确定您的确切用例是什么,但验证器通常用于实体,因此,在创建或更新实体时会调用它们。在这些情况下,您不想发出额外的查询。

    就像我说的,我不知道你到底想要实现什么,但你可以使用现有的 @Email 验证器(你甚至可以使用 regexp attribute 提供自定义正则表达式)。

    【讨论】:

    • 我试过@Compoenent,但没有成功。我正在尝试验证数据库中是否已经存在新的电子邮件输入以及是否遵循电子邮件正则表达式
    • 可能是因为 Validator 位于 @ComponentScan 中未包含的包中。如果您将 Applicaton 类放在“高于”其他所有包的包中,您甚至不需要它(即在“com.Alex”中)。但同样,我认为您不希望验证器成为托管组件,并且我认为您不想在这里发出查询。你想达到什么目的?
    • 我尝试将包包含在 componentsscan 中,但没有成功。我正在做一个验证字段电子邮件的自定义注释。
    • 是的,我知道了...但是这个注释在哪里使用?您正在检查具有给定电子邮件的用户是否存在。这告诉我,您实际上想要某种关系,例如,现有用户下的订单。
    • 在用户类类型级别。是的说新用户输入电子邮件,新电子邮件不应该已经存在于其他现有用户的对象中。我把项目上传到github上给你看看好不好?
    【解决方案2】:

    修复了将以下内容添加到 application.properties。不知道为什么,但它有效

    spring.jpa.properties.javax.persistence.validation.mode=none
    

    【讨论】:

    • 什么有效?注入还是实际验证?因为那应该关闭验证。
    • 这个问题现在运行没有nullexception。但是,运行注释会使我在 .retrieveAllUsers 中出现 nullexception。我正在努力解决这个问题
    • 嗯,这与注释无关,您的代码只是有一个错误:allUsers = null; allUsers::add 您将 allUsers 设置为 null。您应该创建一个新的 ArrayList。尽管我认为您不一定需要转换结果。我的四个 repo 扩展了 org.springframework.data.jpa.repository.JpaRepository,它有一个 findAll 方法返回 List。 docs.spring.io/spring-data/jpa/docs/current/api/org/…
    猜你喜欢
    • 1970-01-01
    • 2011-11-17
    • 2014-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2016-08-25
    • 1970-01-01
    相关资源
    最近更新 更多