karthikmunna
karthikmunna

Reputation: 139

@valid annotation is not working as expected

I am calling an API with the array of objects in the request payload, I have added @valid annotation along the @RequestBody to check if any null properties are sending in my payload. I am expecting if any null data i'm sending it should throw an error. But My code is not throwing an error

Below is my Entity Class

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@DynamicUpdate
@Entity
@Table(name = "student")
public class Student {

   @Id
   @Column(name = "student_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer studentId;

   @NotNull
   @Column(name = "name")
   private String name;

   @NotNull
   @Column(name = "gender")
   private String gender;

}

This is my Controller Class

@RestController
@CrossOrigin
public class StudentController {

   @PostMapping("/class/{classId}/student")
   public Student addStudent(@PathVariable Integer classId,@Valid @RequestBody List<Student>  
           student) {

     // My logic Comes Here
     return Student;
    }
  }

Dependency for Validation

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

My Request Payload

[{
   "name":"kiran",
   "gender":"male"
 },
 {
    "name":"divya"
 } 
]

When i send the above payload, i expect an error need to thrown, because i'm not sending gender which is not null, But spring is not throwing any error.

Do i miss something for @valid to work .

Upvotes: 4

Views: 22969

Answers (7)

Tobias
Tobias

Reputation: 7415

If you're using Kotlin, you need to use

  @field:Email() val email: String

instad of

  @Email() val email: String

for the validation to work.

See https://kotlinlang.org/docs/annotations.html#annotation-use-site-targets and https://stackoverflow.com/a/36521309/570168

Upvotes: 4

T T
T T

Reputation: 11

I know you are working with a Maven built but I had encountered similar issue that tags would not work integrated in a Gradle built.

I solved it by getting the right version of the dependency.

implementation 'org.springframework.boot:spring-boot-starter-validation:2.4.0'

instead of

implementation 'org.springframework.boot:spring-boot-starter-validation'

If anybody knows if this is even correct but it works now.

Upvotes: 1

Esther
Esther

Reputation: 325

If your experiencing the issue of for example: not being able to see the validation errors (default-messages) returned back to the client, this is what you could do:

Top Solution 1: Simply add devtools. This should solve the issue. After I did this, all my binding-results were returned back to the client. I recommend you to test this out first:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
</dependency>

Solution 2:

I found out that this is due to using Spring Boot 2.3+ So if youre using Spring Boot 2.3 or higher, add this dependency in your pom.xml file as its no longer included within the 'web'-dependency itself.

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Now its necessary to set 'include binding errors' in java/resources/application.properties to "always". Same goes for 'message' as well although I think this is optional.

server.error.include-message=always
server.error.include-binding-errors=always

Solution 3: (before I discovered solution 2 which could be helpful as well)

So I found out that this is due to having Spring boot 2.3+. But I could not find caution-messages on the new updated usage of @Valid in Spring Boot v2.3+.

So I ended up switching back to Spring boot v2.2.10 (latest version of 2.2) by adjusting the release version in the pom.xml file like so:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.10.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

This worked perfectly for me by rolling back to an older version. Although id like to update my Spring Boot version some day. (Revisit solution 1 & 2)

Upvotes: 4

Lusmilo Campos
Lusmilo Campos

Reputation: 71

if you use Spring boot 2.3.3.RELEASE. then add in the POM the following dependency:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

Example of use:

//update audTipo
@PutMapping("audTipo/{id}")
public ResponseEntity<AudTipo> update(@PathVariable(value="id") Integer audTipoId, 
        @Valid @RequestBody AudTipo audTipoDetils) throws ResourceNotFundException
{   
    
      AudTipo audTipo = audTipoRepository.findById(audTipoId).orElseThrow(()-> new
      ResourceNotFundException("NF " + audTipoId));
      audTipo.setXdesc(audTipoDetils.getXdesc());
      
      return ResponseEntity.ok(this.audTipoRepository.save(audTipo));    
}

Upvotes: 7

sudo
sudo

Reputation: 775

You cannot apply @Valid to a java.util.List

see: Spring MVC - @Valid on list of beans in REST service

Upvotes: 2

Haris
Haris

Reputation: 188

Your @Valid annotation is applied to the List and not the actual objects present on the list.

The annotation you have in your example validates the list and not each object of the list.

Try this

public Student addStudent(@PathVariable Integer classId,@RequestBody List<@Valid Student> students)

You can specify additional parameters as well for example you may need to validate each object on the list AND to make sure that the list is not empty, or has a minimum size etc. Those validations must be performed on the list.

Upvotes: 2

When Spring Boot finds an argument annotated with @Valid, it automatically bootstraps the default JSR 380 implementation — Hibernate Validator — and validates the argument.

JSR 380 implementation gets violated only when the Request itself is NULL. As mentioned above it cannot be used to check null values in the request body.

Upvotes: 0

Related Questions