spring数据递归验证

zfciruhq  于 2021-08-25  发布在  Java
关注(0)|答案(2)|浏览(461)

这种类型的验证有效吗?
注解:

  1. @Constraint(validatedBy = UniqueEmailValidator.class)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Target({ElementType.FIELD})
  4. public @interface UniqueEmail {
  5. public String message() default "Error message";
  6. public Class<?>[] groups() default {};
  7. public Class<? extends Payload>[] payload() default {};
  8. }

验证器:

  1. @Component
  2. public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
  3. @Autowired
  4. private UserRepository userRepository;
  5. @Override
  6. public boolean isValid(String value, ConstraintValidatorContext context) {
  7. return userService.isEmailUnique(value); // read as a call to userRepository.findByEmail(emailAddress)
  8. }
  9. }

以及实体

  1. @Entity
  2. public class User {
  3. ...
  4. @UniqueEmail
  5. private String email;
  6. }

它失败是因为在 isValid() 方法与 userRepository.findByEmail() . 这是正确的行为吗?是吗 findByEmail 是否始终创建新用户并对其应用验证?
更新:
stacktrace的一部分:

  1. java.lang.StackOverflowError: null
  2. ...
  3. (many times)
  4. ...
  5. UserService.isEmailUnique(UserService.java:84)
  6. ...
  7. UniqueEmailValidator.isValid(UniqueEmailValidator.java:29)
  8. UniqueEmailValidator.isValid(UniqueEmailValidator.java:13)

财产 spring.jpa.properties.javax.persistence.validation.mode=none 解决这个问题。但这仍然不是一个好消息 double validation .

ss2ws0br

ss2ws0br1#

回答我自己的问题。
谢谢你的提示:
在验证中,您正在对同一实体执行查询,这意味着在执行查询之前,hibernate需要刷新会话中排队的内容。
换句话说,如果我做对了,在本例中,hibernate会在验证之前保存它的查询。
因此,我为我的方法添加了相同的传播:

  1. @Transactional(propagation = Propagation.NOT_SUPPORTED)
  2. Optional<User> findByEmail(String email);

它起作用了。
而且我也不需要保留 spring.jpa.properties.javax.persistence.validation.mode=none 不再

v64noz0r

v64noz0r2#

您不应该使用find with entities来检查中是否存在电子邮件地址

  1. userService.isEmailUnique(value)

为什么不创建一个方法:

  1. int countByEmail(String email)

相关问题