0

I using RestController update data to db but I have problem. When i update value, if value from my update is null , it allways update data to db is null. I dont't want it. I want if 1 field with value is null from my request, i don't want update it.

This bellow my code :

Controller:

RestController

@RequestMapping("/api/products")
@Api(value = "ProductControllerApi",produces = MediaType.APPLICATION_JSON_VALUE)

public class ProductController {

    @Autowired
    private ProductService productService;

    @PatchMapping("/{id}")
    public ResponseEntity<ProductResDto> updateProduct(@RequestBody ProductReqDto productReqDto, @PathVariable String id) {
        return ResponseEntity.ok(productService.updateProduct(product,id));
    }

ProductReqDto:

     public class ProductReqDto {

    private String name;
    private String type;
    private String category;
    private String description;
    private Double prince;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrince() {
        return prince;
    }

    public void setPrince(Double prince) {
        this.prince = prince;
    }
}

ProductResDto:

   public class ProductResDto {

    private String name;
    private String type;
    private String category;
    private Double prince;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Double getPrince() {
        return prince;
    }

    public void setPrince(Double prince) {
        this.prince = prince;
    }
}

MappingDto:

private ProductDto convertToProductDto(ProductReq product) {
    return modelMapper.map(product, ProductResDto.class);
}

How to i handle method convertToProductDto only mapping with value not null. Because if , mapping one field : example : product_name = null , it insert to db null. I want if field ProductReq have value, it mapping and keep other different field in database(not set it null if not contain value from ProductReq) . Example:

**ReqProductDto.class**   
    private String name;
    private String type;
    private String category;
    private String description;
    private Double prince;

but if user only update two field:

   private String name;
    private String type;

I want spring update field name, and field type user input and keep category,description,prince in my database. In my case, if user update two field: name, and field type,spring update it but spring set category,description,prince is null in my database. I don't want it. Please help me, thanks.

2 Answers2

0

You've tagged this as spring-boot, so I'm assuming you might be using controllers and validating their parameters. If that is the case, just do

import javax.validation.constraints.NotNull;

public class ProductReqDto {

    @NotNull
    private String name;
    @NotNull
    private String type;
    @NotNull
    private String category;
    @NotNull
    private String description;
    @NotNull
    private Double prince;

    ...

}

and use @Valid for your controllers like this

@PatchMapping("/{id}")
public ResponseEntity<ProductResDto> updateProduct(@RequestBody @Valid ProductReqDto productReqDto, @PathVariable String id) {
    return ResponseEntity.ok(productService.updateProduct(product,id));
}

Then your object will be validated on instantiation.

Dmitry Krivolap
  • 1,354
  • 9
  • 16
  • I know it but i want if one field not required null, but user forgot set it, it not mapping into database.Value field user not set keep value in database. Not set null – Trungtbdnvn11 Mar 13 '19 at 16:14
0

What you want is mainly used for PATCH mapping. IN a PUT mapping, all fields of an object need to override, but in a PATCH mapping only the fields which are provided needs to be overridden, others need not be changed.

So, for an existing record,

employee{ employeeId = "A2RTD", empName = "satish", "country": "India"}

And, now one non-mandatory field mobileNo needs to be updated along with the country

DTO request will contain all field other than id, but only country & mobile no will not be null

In this scenario, we can use BeanUtils which is part of spring package

import org.springframework.beans.BeanUtils;

public static Object getDtoMapping(Object source, Object destination) {
    BeanUtils.copyProperties(source, destination, getNullFieldNames(source));
    return destination;
}

public static String[] getNullFieldNames(Object source) {
    final BeanWrapper src = new BeanWrapperImpl(source);
    PropertyDescriptor[] pds = src.getPropertyDescriptors();

    Set<String> fieldNames = new HashSet<>();
    for (PropertyDescriptor pd : pds) {
        Object srcValue = src.getPropertyValue(pd.getName());
        if (srcValue == null)
            fieldNames.add(pd.getName());
    }

    String[] result = new String[fieldNames.size()];
    return fieldNames.toArray(result);
}

Ths function "getNullFieldNames" will return fieldNames which have value null. So, those fields will not be mapped, as per 3rd optional paramter in BeanUtils

And, you need to pass

// PATCH
EmployeeDao emp = findById(empCode);
emp = (EmployeeDao) getDtoMapping(empUpdateDto, emp);

Here, in BeanUtil copyProperties, 3rd param is optional. If you give it works for PATCH mapping, if you don't give it behaves as PUT mapping.

Since, for PUT mapping, ignoring null as same as not ignoring. You can use the same in POST, PUT mapping also.

// POST MAPPING
EmployeeDao emp = (EmployeeDao) getDtoMapping(empCreateDto, new Employee());
Rolando Isidoro
  • 4,983
  • 2
  • 31
  • 43
Satish Patro
  • 3,645
  • 2
  • 27
  • 53