javax.validation.valid on child objects

10,203

Solution 1

Just Add @Valid to your childList and it should work

public class Parent {
@Size(min = 5, max = 10)
String lastName;
@Valid
List<Child> childs;

}

Solution 2

You can make use of validation groups. In that case your model might look like:

public class Parent {

    @Size(min = 5, max = 10, groups = { Draft.class, FinalVersion.class })
    String lastName;
    @Valid
    List<Child> childs;
}

public class Child {

    @Size(min = 5, max = 10, groups = FinalVersion.class)
    String firstName;
    @Range(min = 1, max = 18, groups = FinalVersion.class)
    Integer age;

}

Also note that @Size is not supported for Integer type - you might want to use either @Range or a pair of @Min @Max (which is essentially the same thing). Draft and FinalVersion are just simple interfaces, to define validation groups:

interface Draft {
}

interface FinalVersion {
}

And then in your controllers you need to use @Validated on your bean parameter instead of @Valid, as first one allows you to choose validation group. So your controller then will look like:

@ResponseBody
@RequestMapping(value = "saveDraft", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public RestResponse create(@RequestBody @Validated(Draft.class) Parent object) {
    // your stiff here
}

@ResponseBody
@RequestMapping(value = "submitFinal", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
public RestResponse create(@RequestBody @Validated(FinalVersion.class) Parent object) {
    // your stiff here
}

But you'll need to have two methods to handle the post - one for draft and one for final submit.

Share:
10,203

Related videos on Youtube

shha
Author by

shha

Updated on June 04, 2022

Comments

  • shha
    shha almost 2 years

    I've got a simple structure

    public class Parent {
        @Size(min = 5, max = 10)
        String lastName;
        List<Child> childs;
    }
    
    public class Child {
        @Size(min = 5, max = 10)
        String firstName;
        @Size(min = 1, max = 18)
        Integer age;
    }
    

    and a method with definition

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces="application/json")
    public RestResponse create(@RequestBody Parent object)
    

    which creates (and gives a possibility to update) parent objects.

    Let's assume that I'd like to create two functionalities:

    1) To create a working copy - user doesn't have to insert correctly all of the data.

    2) To send me this data - in this example I'd like to valid if they're correct.

    I've found that there is a way to valid it by adding @Valid annotation to the parameter in method definition, like that:

    @ResponseBody
    @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces="application/json")
    public RestResponse create(@RequestBody @Valid Parent object)
    

    but it do valid only parent field, skipping childs. I can add @Valid annotation on child list:

    public class Parent {
        @Size(min = 5, max = 10)
        String lastName;
        List<Child> childs;
    }
    

    but it'll work all the time - even when I'd like to save a working copy. Is it possible to valid objects inside parent object conditionally?

  • spyro
    spyro almost 3 years
    For Kotlin data classes, @field@valid or @get@valid will do.