@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 forPerson
).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
onfatherDto
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
Access "This" from Java Anonymous Class
Why Would One Declare a Java Interface Method as Abstract
Jackson JSON Custom Serialization for Certain Fields
When Using == for a Primitive and a Boxed Value, Is Autoboxing Done, or Is Unboxing Done
Why Is Files.Lines (And Similar Streams) Not Automatically Closed
Turning an Executorservice to Daemon in Java
Detect If Java Application Was Run as a Windows Admin
Java - Using Accessor and Mutator Methods
Apache Httpclient Making Multipart Form Post
Closing a Joptionpane Programmatically
Get the Week Start and End Date Given a Current Date and Week Start
Java.Sql.Sqlexception: No Suitable Driver Found for Jdbc:Mysql://Localhost:3306/Dbname