Skip to content
Advertisement

Spring @Valid annotation not working as validating dto fields?

I have checked many other questions about it but I cannot find the solution, where am I missing ?

Here is the controller method:

package com.nishberkay.nishcustomer.controller;

import com.nishberkay.nishcustomer.dto.request.CustomerAddRequestDto;
import com.nishberkay.nishcustomer.dto.request.CustomerUpdateRequestDto;
import com.nishberkay.nishcustomer.dto.response.CustomerDto;
import com.nishberkay.nishcustomer.entity.mysqlentity.Customer;
import com.nishberkay.nishcustomer.exception.InvalidRequestException;
import com.nishberkay.nishcustomer.service.CustomerService;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/customer")
@Validated
public class CustomerController {


    private CustomerService customerService;
    private ModelMapper modelMapper;

    @Autowired
    public CustomerController(CustomerService customerService, ModelMapper modelMapper) {
        this.customerService = customerService;
        this.modelMapper = modelMapper;
    }

    @PutMapping
    public CustomerDto updateCustomer(@Valid @RequestBody CustomerUpdateRequestDto customerDto,
                                      BindingResult bindingResult) throws Exception {
        if (bindingResult.hasErrors()) {
            String errorMessage = bindingResult.getAllErrors().get(0).getDefaultMessage();
            throw new InvalidRequestException(errorMessage);
        }
        Customer customer = modelMapper.map(customerDto, Customer.class);
        return modelMapper.map(customerService.update(customer), CustomerDto.class);
    }
}

And my dto is:

import javax.validation.constraints.NotNull;

@Data
public class CustomerUpdateRequestDto {

    @NotNull
    private int id;

    @NotNull
    private String firstName;

    @NotNull
    private String lastName;
}

My problem is (maybe @Valid is actually working I am not sure), when I debug it with the postman request:

{
    "firstName" : "berkayaaasd",
    "lastName" : "dada"
}

I am expecting some kind of message like “Id cannot be null” but id field is coming as 0 so thats why I think maybe @Valid is working but something else is wrong.

And here is the pom dependencies:

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.modelmapper</groupId>
            <artifactId>modelmapper</artifactId>
            <version>2.3.8</version>
        </dependency>
    </dependencies>

Advertisement

Answer

The issue here is that you defined your id as a primitive type, which can never be null.

If you chose a boxed type (Integer in this case) this should work.

So in your DTO:

import javax.validation.constraints.NotNull;

@Data
public class CustomerUpdateRequestDto {
    @NotNull
    private Integer id;
    ...
}
Advertisement