我正在使用JPA 2.0 /hibernate验证来验证我的模型。我现在遇到一种情况,必须验证两个字段的组合:
public class MyModel { public Integer getValue1() { //... } public String getValue2() { //... } }
该模型是无效的,如果都getValue1()和getValue2()都null和其他有效。
getValue1()
getValue2()
如何使用JPA 2.0 / Hibernate执行这种验证?使用简单的@NotNull注释,两个吸气剂都必须为非null才能通过验证。
@NotNull
对于多属性验证,应使用类级别的约束。摘自 Bean Validation Sneak Peek第二部分:自定义约束:
类级别的约束
你们中有些人对应用跨越多个属性的约束或表达依赖于多个属性的约束的能力表示担忧。经典示例是地址验证。地址具有复杂的规则:
``` @AddressAnnotation public class Address { @NotNull @Max(50) private String street1; @Max(50) private String street2; @Max(10) @NotNull private String zipCode; @Max(20) @NotNull String city; @NotNull private Country country;
...
}
@Constraint(validatedBy = MultiCountryAddressValidator.class) @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface AddressAnnotation { String message() default “{error.address}”; Class<?>[] groups() default { }; Class<? extends Payload>[] payload() default { }; }
public class MultiCountryAddressValidator implements ConstraintValidator { public void initialize(AddressAnnotation constraintAnnotation) { // initialize the zipcode/city/country correlation service }
/** * Validate zipcode and city depending on the country */ public boolean isValid(Address object, ConstraintValidatorContext context) { if (!(object instanceof Address)) { throw new IllegalArgumentException("@Address only applies to Address"); } Address address = (Address) object; Country country = address.getCountry(); if (country.getISO2() == "FR") { // check address.getZipCode() structure for France (5 numbers) // check zipcode and city correlation (calling an external service?) return isValid; } else if (country.getISO2() == "GR") { // check address.getZipCode() structure for Greece // no zipcode / city correlation available at the moment return isValid; } // ...
``` } }
高级地址验证规则已被排除在地址对象之外,并由实现 MultiCountryAddressValidator。通过访问对象实例,类级别的约束具有很大的灵活性,并且可以验证多个相关属性。请注意,这里的排序不包括方程式,我们将在下一篇文章中再次讨论。
专家组讨论了多种属性支持方法:与其他涉及依赖的属性级别方法相比,我们认为类级别约束方法既提供了足够的简便性又提供了灵活性。欢迎您提供反馈。