@Valid Annotation Is Not Validating the List of Child Objects

@Valid annotation is not validating the list of child objects

You need to decorate addresses member of UserAddressesForm with @Valid annotation. See section 3.1.3 and 3.5.1 of JSR 303: Bean Validation. As I explained in my answer to the question Is there a standard way to enable JSR 303 Bean Validation using annotated method, this is the real use of @Valid annotation as per JSR 303.

Edit
Example code: Hibernate Validator- Object Graph. (The list of passengers in Car)

Edit From Hibernate Validator 6 Reference doc:

In versions prior to 6, Hibernate Validator supported cascaded validation for a subset of container elements and it was implemented at the container level (e.g. you would use @Valid private List<Person> to enable cascaded validation for Person).

This is still supported but is not recommended. Please use container
element level @Valid annotations instead as it is more expressive.

Example:

public class Car {

private List<@NotNull @Valid Person> passengers = new ArrayList<Person>();

private Map<@Valid Part, List<@Valid Manufacturer>> partManufacturers = new HashMap<>();

//...
}

Also see what's new in Bean Validation 2.0/Jakarta Bean Validation.

@Valid (javax.validation.Valid) is not recursive for the type of list

Have you tried it like this:

class Parent {
@NotNull // javax.validation.constraints.NotNull
private String name;

@Valid
List<Child> children;
}

Javax validation on nested objects - not working

Use @ConvertGroup from Bean Validation 1.1 (JSR-349).

Introduce a new validation group say Pk.class. Add it to groups of BuildingDto:

public class BuildingDto {

@NotNull(groups = {Pk.class, Existing.class, LocationGroup.class})
// Other constraints
private Integer id;

//
}

And then in LocationDto cascade like following:

@Valid
@ConvertGroup.List( {
@ConvertGroup(from=New.class, to=Pk.class),
@ConvertGroup(from=LocationGroup.class, to=Pk.class)
} )
// Other constraints
private BuildingDto building;

Further Reading:

5.5. Group conversion from Hibernate Validator reference.

Is there an annotation for java validate if the value of a field in a List of Objects is duplicated?

Edited

For validating the child emails list, you can create a custom validation.

I coded a custom validation as follows

1- Create annotation named ChildEmailValidation

@Documented
@Constraint(validatedBy = ChildEmailValidator.class)
@Target( { ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ChildEmailValidation {

String message() default "Duplicate Email";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

2- Create a validator for ChildEmailValidation

In this part, you can write your custom business for validation. (You can write your algorithm)

    public class ChildEmailValidator implements ConstraintValidator<ChildEmailValidation, List<Child>> {

@Override
public void initialize(ChildEmailValidation constraintAnnotation) {

}

@Override
public boolean isValid(List<Child> childList, ConstraintValidatorContext constraintValidatorContext) {

//Create empty mailList
List<String> mailList = new ArrayList<>();

//Iterate on childList
childList.forEach(child -> {

//Checks if the mailList has the child's email
if (mailList.contains(child.getMail())) {

//Found Duplicate email
throw new DuplicateEmailException();

}

//Add the child's email to mailList (If duplicate email is not found)
mailList.add(child.getMail());

});

//There is no duplicate email
return true;
}

}

3- Add @ChildEmailValidation in Father class

public class Father {

List<Child> child;

@ChildEmailValidation
public List<Child> getChild() {
return child;
}

public void setChild(List<Child> child) {
this.child = child;
}
}

4- Put @Valid on fatherDto in the controller

@RestController
@RequestMapping(value = "/test/", method = RequestMethod.POST)
public class TestController {

@RequestMapping(value = "/test")
public GenericResponse getFamily(@RequestBody @Valid Father fatherDto) {
// ...
}

}


Related Topics



Leave a reply



Submit