spring数据递归验证

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

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

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

验证器:

@Component
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
  @Autowired
  private UserRepository userRepository;

  @Override
  public boolean isValid(String value, ConstraintValidatorContext context) {
      return userService.isEmailUnique(value); // read as a call to userRepository.findByEmail(emailAddress)
  }
}

以及实体

@Entity
public class User {
  ...
  @UniqueEmail
  private String email;
}

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

java.lang.StackOverflowError: null
...
(many times)
...
UserService.isEmailUnique(UserService.java:84)
...
UniqueEmailValidator.isValid(UniqueEmailValidator.java:29)
UniqueEmailValidator.isValid(UniqueEmailValidator.java:13)

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

ss2ws0br

ss2ws0br1#

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

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

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

v64noz0r

v64noz0r2#

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

userService.isEmailUnique(value)

为什么不创建一个方法:

int countByEmail(String email)

相关问题