Problem already solved here but didn't work for me (not same spring boot version i guess) this
Trying to code a custom constraint validator, to check whether account email exists before persisting.
@Email
@NotNull
@NotBlank
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UniqueCompteEmailValidator.class)
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
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, String> {
@Autowired
private CompteRepository compteRepository;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return value != null && this.compteRepository.findByEmail(value) == null;
}
}
// --------------------------------------------------------------------------
@Configuration
public class OtherConfigurations {
//----
@Bean
public Validator validator(@Autowired AutowireCapableBeanFactory autowireCapableBeanFactory) {
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
.constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory))
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
}
// --------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.mssmfactory</groupId>
<artifactId>bacsimulator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>bacsimulator</name>
<description>BAC Simulator</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
My problem is that private CompteRepository compteRepository always contains null, and from my stacktrace, i can see that it's being instanciated by hibernate-validation instead of being instanciated by spring and used by hibernate.
Any idea ?
The issue that you are facing is because the
@Autowired
annotation is not working for you when you autowireCompteRepository.class
.You can autowire components in your validation class but make sure that you use spring to create the validator bean otherwise the bean injection won't work as manually creating validator bean using valdiation factory (Hibernate Validator as reference implentation) does not inject dependencies into ConstraintValidator instances.So, you cannot use the validator factory to create the validator instance , instead autowire it and everything should work.
Changed hibernate's bean validator factory by this @Component class and now it works so well