Wondering why Spring is not getting the Hibernate Bean Validation kicked in. According to the documentation HERE, it requires a MethodValidationPostProcessor
in the context and the target spring bean to be annotated with @Validated
annotation. I got both of these requirements done, but it is still not working.
I expected an exception at the call to backgroundCheck
method due to the fact that the person's name is null
and the age is less than 18. For some reason, however, the Person
object is not being validated and the method finishes without exceptions.
Here is my setup:
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
@Override
public void run(String... args) {
PersonService personService = new PersonService();
try {
personService.backgroundCheck(new Person(null, 4));
} catch (Exception e) {
System.out.println("<<< EXCEPTION >>>");
return;
}
System.out.println("<<< NO VALIDATIONS THROWN >>>");
}
}
import jakarta.validation.Valid;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@Validated
@Service
public class PersonService {
public void backgroundCheck(@Valid Person person) {
System.out.printf("Running background check for %s%n", person.name());
}
}
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
public record Person(
@NotBlank(message = "Name must not be blank")
String name,
@Min(value = 18, message = "Age should not be less than 18")
int age) {
}
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Any idea what I am missing?
org.springframework.validation.annotation.Validated
@Validated must be a Spring Bean to perform validation.
@SpringBootApplication
public class Application implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public LocalValidatorFactoryBean validator() {
return new LocalValidatorFactoryBean();
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
return methodValidationPostProcessor;
}
// register spring bean!
@Bean
public PersonService personService() {
return new PersonService();
}
@Override
public void run(String... args) {
try {
personService().backgroundCheck(new Person(null, 4));
} catch (ConstraintViolationException e) {
System.out.println("<<< EXCEPTION >>>");
return;
}
System.out.println("<<< NO VALIDATIONS THROWN >>>");
}
}
2024-03-20T13:09:23.676+09:00 INFO 4384 --- [ main]
<<< EXCEPTION >>>
I hope it will be of help :) thanks.