In this post, we will see Hibernate Validator Constraints Example Using Spring Boot. Suppose we have an entity and we want to validate fields defined in the entity, we can use validators with fields. We are going to use validation-api-2.0 and hibernate-validator-6.0.9. The validation-api 2.0 also Known as JSR-380 i.e Java Specification Requests -380) .
Let’s see a sample example of an entity where we are using different annotations for the fields validation.
@Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "student_name") @NotEmpty private String studentName; @Column(name = "roll_number") @Size(max = 10, message = "RollNumber can't be more than 10 character") private String rollNumber; @Column(name = "marks") @Max(1000) private int marks; @Column(name = "phone_number") @Size(min = 10, max = 10, message = "PhoneNumber should be 10 digit") private String phoneNumber; @Column(name = "email") @Email(message = "Please provide a valid email") private String email; }
Before going ahead let’s see what we are going to do. We will define a global error handler for error messages using @ControllerAdvice and @Exceptionhandler. Also, we will have one REST API which will use to save the data in the database. If we have a valid request we will able to save data in the database else it should show error messages.
REST API – http://localhost:9091/student/save
Valid Request Data –
{ "studentName": "rakesh", "rollNumber": "0126CS01", "marks": 789, "phoneNumber": 7411026754, "email": "rakeshranjan673@gmailcom" }
Response data –
{ "id": 1, "studentName": "rakesh", "rollNumber": "0126CS01", "marks": 789, "phoneNumber": "7411026754", "email": "rakeshranjan673@gmailcom" }
Invalid Request Data – Make name attribute empty, give rollNumber more than 10 character, give marks more than 1000 , provide a phoneNumber more than 10 digits and also don’t give @ in emailid.
{ "studentName":"", "rollNumber":"0126CS0111111111", "marks": 4566, "phoneNumber":"741102675498222", "email":"rakeshranjan673gmailcom" }
Response data –
{ "errorMessage": [ "rollNumber : RollNumber can't be more than 10 character", "studentName : must not be empty", "email : Please provide a valid email", "marks : must be less than or equal to 1000", "phoneNumber : PhoneNumber should be 10 digit" ], "statusCode": 400 }
Let’s see complete Hibernate Validator Constraints Example Using Spring Boot from scratch.
Open eclipse and create maven project, Don’t forget to check ‘Create a simple project (skip)’ click on next. Fill all details as below and click on finish.
Modify pom.xml
<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> <groupId>hibernatevalidatorexample</groupId> <artifactId>hibernatevalidatorexample</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hibernatevalidatorexample</name> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0.3</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}</finalName> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <fork>true</fork> <executable>C:\Program Files\Java\jdk1.8.0_131\bin\javac.exe</executable> </configuration> </plugin> </plugins> </build> </project>
Note – In pom.xml we have defined javac.exe path in configuration tag. You need to change accordingly i.e where you have installed JDK.
If you see any error for oracle dependency then follow these steps.
Directory structure –
Student.java
package com.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.validation.constraints.Email; import javax.validation.constraints.Max; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @Column(name = "student_name") @NotEmpty private String studentName; @Column(name = "roll_number") @Size(max = 10, message = "RollNumber can't be more than 10 character") private String rollNumber; @Column(name = "marks") @Max(1000) private int marks; @Column(name = "phone_number") @Size(min = 10, max = 10, message = "PhoneNumber should be 10 digit") private String phoneNumber; @Column(name = "email") @Email(message = "Please provide a valid email") private String email; }
StudentController.java
package com.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import com.entity.Student; import com.service.StudentService; @RestController @RequestMapping(value = "/student") public class StudentController { @Autowired private StudentService studentService; @RequestMapping(value = "/save", method = RequestMethod.POST) @ResponseBody public Student saveBook(@RequestBody Student student) { Student studentResponse = (Student) studentService.saveStudent(student); return studentResponse; } }
StudentRepository.java – interface
package com.repository; import java.io.Serializable; import org.springframework.data.repository.CrudRepository; import org.springframework.stereotype.Repository; import com.entity.Student; @Repository public interface StudentRepository extends CrudRepository<Student,Serializable> { }
StudentService.java – interface
package com.service; import org.springframework.stereotype.Component; import com.entity.Student; @Component public interface StudentService { public Student saveStudent(Student student); }
StudentServiceImpl.java
package com.impl; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import javax.validation.Validation; import javax.validation.Validator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.entity.Student; import com.repository.StudentRepository; import com.service.StudentService; @Service("studentServiceImpl") public class StudentServiceImpl implements StudentService { @Autowired private StudentRepository studentRepository; @Override public Student saveStudent(Student student) { validateEntity(student); Student studentresponse = studentRepository.save(student); return studentresponse; } private void validateEntity(Student student) { List<String> errorMessage = new ArrayList<>(); Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); Set<ConstraintViolation<Student>> constraintViolations = validator.validate(student); for (ConstraintViolation<Student> constraintViolation : constraintViolations) { errorMessage.add(constraintViolation.getMessage()); } if (errorMessage.size() > 0) { throw new ConstraintViolationException(constraintViolations); } } }
GlobalErrorHandler.java – Let’s define a error handler class. This class will be used when validateEntity() method will throw ConstraintViolationException(See more details about GlobalErrorHandler here).
package com.controller; import java.util.List; import java.util.ArrayList; import javax.validation.ConstraintViolation; import javax.validation.ConstraintViolationException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import com.entity.ResponseError; @ControllerAdvice public class GlobalErrorHandler { @ExceptionHandler(ConstraintViolationException.class) @ResponseBody public ResponseError handleCustomException(ConstraintViolationException ex) { ResponseError responseError = new ResponseError(); List<String> errorMessages = new ArrayList(); for (ConstraintViolation constraintViolation : ex.getConstraintViolations()) { errorMessages.add(constraintViolation.getPropertyPath() + " : " + constraintViolation.getMessage()); } responseError.setErrorMessage(errorMessages); responseError.setStatusCode(HttpStatus.BAD_REQUEST.value()); return responseError; } }
ResponseError.java
package com.entity; import java.util.List; public class ResponseError { private List<String> errorMessage; private int statusCode; public List<String> getErrorMessage() { return errorMessage; } public void setErrorMessage(List<String> errorMessage) { this.errorMessage = errorMessage; } public int getStatusCode() { return statusCode; } public void setStatusCode(int statusCode) { this.statusCode = statusCode; } }
SpringMain.java
package com.main; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.context.annotation.ComponentScan; @SpringBootApplication @ComponentScan(basePackages = "com.*") @EntityScan("com.entity") public class SpringMain { public static void main(String[] args) { SpringApplication.run(SpringMain.class, args); } }
JpaConfig.java
package com.config; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @Configuration @EnableJpaRepositories(basePackages = "com.repository") public class JpaConfig { }
application.properties
# Connection url for the database spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE spring.datasource.username=SYSTEM spring.datasource.password=oracle2 spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver # Show or not log for each sql query spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto =create spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.Oracle10gDialect server.port = 9091
Let’s run the example.
Let’s see some important validation constraints which have been defined in validation-api-2.0. These annotations have been defined in javax.validation.constraints package. Apart from this, it has been defined some more validation constraints which we will see later.
@NotEmpty – If we use this annotation with some field that field must not be null nor empty.
@Size – If we use this annotation with some field that field size must be between the specified boundaries (included).
@NotNull – If we use this annotation with some field that field must not be null.
@NotBlank – If we use this annotation with some field that field must contain at least one non-whitespace character.
@Email – If we use this annotation with some field that field should well-formed email address.
@Max – If we use this annotation with some field that field must be a number whose value must be lower or equal to the specified maximum.
@Min – If we use this annotation with some field that field must be a number whose value must be higher or equal to the specified minimum.
@Digits – If we use this annotation with some field that field must be a number within accepted range Supported types are BigDecimal BigInteger CharSequence byte, short, int, long, and their respective wrapper types.
@Null – If we use this annotation with some field that field must be null.
@AssertFalse – If we use this annotation with some field or property that field must be false.
@AssertTrue – If we use this annotation with some field or property that field must be true.
@DecimalMax – The value of the field or property must be a decimal value lower than or equal to the number in the value element.
@DecimalMin – The value of the field or property must be a decimal value greater than or equal to the number in the value element.
@Future – The value of the field or property must be a date in the future.
@FutureOrPresent – The value of the field or property must be a date or time in present or future.
@Negative – The value of the field or property must be negative.
@NegativeOrZero – The value of the field or property must be negative or zero.
@Past – The value of the field or property must be a date in the past.
@PastOrPresent – The value of the field or property must be a date or time in the past or present.
@Pattern – The value of the field or property must match the regular expression defined in the regexp element.
@Positive – The value of the field or property must be a positive number.
@PositiveOrZero – The value of the field or property must be a positive number or zero.
Apart from the above annotations, in org.hibernate.validator.constraints package we have some more annotations.
@Length – Used to validate the length of fields.
@CreditCardNumber -Used to validate credit card number.
@Range -We can give a range of fields. Apply on numeric values or a string representation of the numeric value.
@URL – Used to validate URL.
See here some more Hibernate Validator Constraints which belongs to org.hibernate.validator.constraints package.
That’s all about Hibernate Validator Constraints Example Using Spring Boot.
You may like –
- @Temporal Annotation Example In Hibernate/Jpa Using Spring Boot.
- @ControllerAdvice Global Error Handling Example in Spring Boot.
- Hibernate Table Per Concrete Class Spring Boot.
- Hibernate Table Per Subclass Inheritance Spring Boot.
- Hibernate Single Table Inheritance using Spring Boot.
- One to One Mapping Annotation Example in Hibernate/JPA using Spring Boot and Oracle.
- One to One Bidirectional Mapping Example In Hibernate/JPA Using Spring Boot and Oracle.
- One To Many Mapping Annotation Example In Hibernate/JPA Using Spring Boot And Oracle.
- One To Many Bidirectional Mapping In Hibernate/JPA Annotation Example Using Spring Boot and Oracle
- Many To One Unidirectional Mapping In Hibernate/JPA Annotation Example Using Spring Boot and Oracle.
- Many To Many Mapping Annotation Example In Hibernate/JPA Using Spring Boot And Oracle.
See Docs.