Although I found some similar problems (here and here for example) it did not completely answer my problem, as I used spring Boot 2.4.4, or simply don't work. My problem is that repository becomes null
during second (JPA) validation. Here is the detail :
I use Spring Boot, and Bean Validation, via the spring-boot-starter-validation dependency
.
I have a custom validator to check if an email exists in database. First I declare the @EmailExisting
annotation :
@Documented
@Constraint(validatedBy = EmailValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EmailExisting {
String message() default "Email already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Then the custom validator, with the repository injected to check Database :
public class EmailValidator implements
ConstraintValidator<EmailExisting, String> {
@Autowired
UserRepository userRepository;
@Override
public boolean isValid(String email,
ConstraintValidatorContext cxt) {
List<User> users = userRepository.findByEmail(email);
if (!users.isEmpty()) {
return false;
}
return true;
}
}
Finally the SPRING MVC part, with the @Valid
annotation to trigger validation :
@Autowired
UserRepository userRepository;
@PostMapping(value = "/users")
public ResponseEntity addUSer(@Valid @RequestBody User user) {
user.setEmail(user.getEmail());
user.setLastName(StringUtils.capitalize(user.getLastName()));
user.setFirstName(StringUtils.capitalize(user.getFirstName()));
userRepository.save(user);
return new ResponseEntity(user, HttpStatus.CREATED);
}
Problem:
When I test the endpoint, I have a NullPointerException
.
At first, during MVC validation the repository is correctly injected. But after, when we call save()
method to save the entity in the controller, the control triggers again, and the repository becomes null
, hence the NullPointerException
.
I found a workaround, to deactivate control on JPA side, with the following configuration :
spring.jpa.properties.javax.persistence.validation.mode=none
It works well, but I think it should be possible to have the repository injected in the 2 cases?
All code is in my repository
Thank you in advance!