'How can I validate two or more fields in combination?
I'm using JPA 2.0/Hibernate validation to validate my models. I now have a situation where the combination of two fields has to be validated:
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
The model is invalid if both getValue1() and getValue2() are null and valid otherwise.
How can I perform this kind of validation with JPA 2.0/Hibernate? With a simple @NotNull annotation both getters must be non-null to pass validation.
Solution 1:[1]
To work properly with Bean Validation, the example provided in Pascal Thivent's answer could be rewritten as follows:
@ValidAddress
public class Address {
@NotNull
@Size(max = 50)
private String street1;
@Size(max = 50)
private String street2;
@NotNull
@Size(max = 10)
private String zipCode;
@NotNull
@Size(max = 20)
private String city;
@Valid
@NotNull
private Country country;
// Getters and setters
}
public class Country {
@NotNull
@Size(min = 2, max = 2)
private String iso2;
// Getters and setters
}
@Documented
@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = { MultiCountryAddressValidator.class })
public @interface ValidAddress {
String message() default "{com.example.validation.ValidAddress.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
public class MultiCountryAddressValidator
implements ConstraintValidator<ValidAddress, Address> {
public void initialize(ValidAddress constraintAnnotation) {
}
@Override
public boolean isValid(Address address,
ConstraintValidatorContext constraintValidatorContext) {
Country country = address.getCountry();
if (country == null || country.getIso2() == null || address.getZipCode() == null) {
return true;
}
switch (country.getIso2()) {
case "FR":
return // Check if address.getZipCode() is valid for France
case "GR":
return // Check if address.getZipCode() is valid for Greece
default:
return true;
}
}
}
Solution 2:[2]
A custom class level validator is the way to go, when you want to stay with the Bean Validation specification, example here.
If you are happy to use a Hibernate Validator feature, you could use @ScriptAssert, which is provided since Validator-4.1.0.Final. Exceprt from its JavaDoc:
Script expressions can be written in any scripting or expression language, for which a JSR 223 ("Scripting for the JavaTM Platform") compatible engine can be found on the classpath.
Example:
@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)")
public class MyBean {
private String value1;
private String value2;
}
Solution 3:[3]
You can use @javax.validation.constraints.AssertTrue validations like this:
public class MyModel {
private String value1;
private String value2;
@AssertTrue(message = "Values are invalid")
private boolean isValid() {
return value1 != null || value2 != null;
}
}
Solution 4:[4]
Programing Language : Java
This is a solution that helped me.
Requirement :
On UI there is a table which contains List of Objects which is having Maping to multiple Tables/Objects with fk relationship.
Now the validation is out of multiple fks there are only 3 columns which can't be duplicated. I mean the combination of 3 can't be duplicated.
Note : As I am working on Custom Framework on Java there is no option to use HashCode or equals. If I will use array index iteration that will increase the time complexity which I don't want.
Solution:
I have prepared a String , which is a custom String that contains ID of FK1#ID of FK2#ID of FK3 Ex: the String will form like -> 1000L#3000L#1300L#
This String, we will add to a set by using add() of set which will return false if duplicate comes up.
Based on this flag we can throw validation message.
This helped me. Some scenario and restriction comes where DS may not help.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | t0r0X |
| Solution 3 | nyxz |
| Solution 4 | Dharman |
