Hi, i want to implement ConstraintsValidator which verifies whether an email is available before registering a new user, using spring’s depandency injection “@Autowired” to inject JPA Repository in the validator to make database search.
i so changed hibernate’s validator factory so that spring instanciate the validator so that i can use @Autowired
Everything works fine, however it’s like the validation is entering a infinite loop which causes a stackoverflowexception.
Note: lthe validation is done automaticlly (i’m not calling validator.validate()) as i’m using REST JPA Repository
@Getter @Setter @Entity @UniqueCompteEmail @Inheritance(strategy = InheritanceType.SINGLE_TABLE) public abstract class Compte implements Serializable, UserDetails { private static final long serialVersionUID = -5230227676515387462L; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private Integer id; @NotBlank @NotNull @Column(unique = true) private String username; @NotNull @NotBlank @Size(min = 6) private String password; @Email @NotNull @NotBlank @Column(unique = true) private String email; @Override public Collection<? extends GrantedAuthority> getAuthorities() { return new HashSet<GrantedAuthority>(); } @Override public String getPassword() { return this.password; } @Override public String getUsername() { return this.username; } @Override public boolean isAccountNonExpired() { return true; } @Override public boolean isAccountNonLocked() { return true; } @Override public boolean isCredentialsNonExpired() { return true; } @Override public boolean isEnabled() { return true; } public abstract CompteType getTypeCompte(); public abstract void setTypeCompte(CompteType typeCompte); public static enum CompteType { ETUDIANT, ADMINISTRATEUR } } @Repository public interface CompteRepository extends JpaRepository<Compte, Integer> { public Optional<Compte> findByUsername(String username); public Optional<Compte> findByEmail(String email); } @Documented @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = UniqueCompteEmailValidator.class) @Target({ ElementType.TYPE }) public @interface UniqueCompteEmail { String message() default "{com.mssmfactory.bacsimulator.uniquecompteemail.message}"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class UniqueCompteEmailValidator implements ConstraintValidator<UniqueCompteEmail, Compte> { @Autowired private CompteRepository compteRepository; @Override public void initialize(UniqueCompteEmail constraintAnnotation) { } @Override public boolean isValid(Compte value, ConstraintValidatorContext context) { if (value != null) { Optional<Compte> compte = this.compteRepository.findByEmail(value.getEmail()); return !compte.isPresent(); } else return false; } } @Component public class ValidatorAddingCustomizer implements HibernatePropertiesCustomizer { @Autowired private ValidatorFactory validatorFactory; public void customize(Map<String, Object> hibernateProperties) { if (validatorFactory != null) { hibernateProperties.put("javax.persistence.validation.factory", validatorFactory); } } }