Hi Emmanuel,
I will try to simplify usecase as possible and I can't use real one because of company privacy.
Code:
public class Email {
private long id;
@Email
@Size(max=100)
private String address;
...
}
Email type has Email and Size constraints. NotEmpty is not used because email could be optional.
Code:
public class Client implements Validatable {
@NotEmpty(children="address", reportOn="primary.address")
@DeepValidation
private Email primary;
@DeepValidation
private Email secondary;
/**
* Custom validation logic.
*/
// Our solution don't have this parameters
public void validate(ConstraintContext constraintContext, Class<?>... groups) {
...
}
}
Client contains primary email and secondary email, primary is required (NotEmpty) and secondary is optional.
Client validation validator.validate(client);
should check constraints:
1. @Email, @Size and @NotEmpty against primary property and report error on primary.address field.
2. @Email and @Size against secondary property and report error on secondary.address field.
3. check business custom validation which can't be automated by annotation. Our solution don't have this parameter
Code:
public class Contact {
@DeepValidation
private Email email;
@DeepValidation
private Address address;
...
}
Contact validation should check constraints:
1. @Email and @Size against email property and report error on email.address field.
2. check other fields
Code:
public class User implements Validatable {
private long id;
@NotEmpty(children="contact.email.address",reportOn="contact.email.address")
@DeepValidation
private Contact contact;
...
public void validate(ConstraintContext constraintContext, Class<?>... groups) {
...
}
}
User validation should check constraints:
1. repeat whole validation logic on Contact type and report error on Contact fields plus contact prefix (Ex. contact.address)
2. @NotEmpty against contact.email.address property.
2. check other fields
3. check business custom validation which can't be automated by annotation.
Code:
public class Group implements Validatable {
@DeepValidation
private List<Contact> contacts;
...
}
Group validation should check constraints:
1. repeat whole validation logic on Contact type for each contacts object and report error on Contact fields plus contacts[index] prefix
(Ex. contacts[2].email.address)
2. check other fields
3. check business custom validation which can't be automated by annotation.
DeepValidation used to define repetition of whole validation of child object type in composite type.
Without that, composite object validation will become nightmare where we have to repeat whole validation logic of child object
with only one difference in additional prefix.
I am not happy with children property in Constraint because I have to know structure of child object.
I rudder prefer validation grouping and use something like:
Code:
public class Email {
private long id;
@Email
@Size(max=100)
@NotEmpty(group="required")
private String address;
...
}
public class Client implements Validatable {
@DeepValidation(childrenGroup="required")
private Email primary;
@DeepValidation
private Email secondary;
...
}
Thanks,
Nenad