Как я могу проверить два или более полей в сочетании?
я использую проверку JPA 2.0/Hibernate для проверки моих моделей. Теперь у меня есть ситуация, когда комбинация двух полей должна быть проверена:
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
модель недействительным если как getValue1()
и getValue2()
are null
и действительны в противном случае.
как я могу выполнить этот вид проверки с JPA 2.0/Hibernate? С помощью простого @NotNull
аннотация оба геттера должны быть ненулевыми для прохождения проверки.
4 ответа:
для проверки нескольких свойств следует использовать ограничения уровня класса. От проверка бобов Sneak Peek Часть II: пользовательские ограничения:
ограничения на уровне класса
некоторые из вас выразили озабоченность о возможности применения ограничение, охватывающее несколько свойства, или выразить ограничение которые зависят от нескольких свойств. Классический пример-адрес утверждение. Адреса у нас замысловатые правила:
- название улицы является несколько стандартным и, безусловно, должно иметь ограничение по длине
- структура почтового индекса полностью зависит от страны
- город часто может быть соотнесен с zipcode и некоторые проверки ошибок может быть сделано (при условии, что проверка услуга доступна)
- из-за этих взаимозависимостей простое ограничение уровня собственностью чтобы соответствовать счету
В решение, предлагаемое фасолью Спецификация проверки является двукратной:
- это дает возможность в силу определенных ограничений применяться перед другой набор ограничений через использование групп и групповых последовательностей. Эта тема будет рассмотрена в следующих разделах: следующая запись в блоге
- это позволяет определить ограничения уровня класс
ограничения уровня класса являются постоянными ограничения (аннотация / реализация дуэта) который нанесите на класс, а не свойство. Сказал иначе говоря, ограничения на уровне класса получить экземпляр объекта (скорее чем значение свойства) в
isValid
.@Address 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 Address { String message() default "{error.address}"; String[] groups() default {}; } public class MultiCountryAddressValidator implements ConstraintValidator<Address> { public void initialize(Address constraintAnnotation) { // initialize the zipcode/city/country correlation service } /** * Validate zipcode and city depending on the country */ public boolean isValid(Object object) { 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
. От доступ к экземпляру объекта класса ограничения уровня имеют много гибкость и может проверить несколько коррелированные свойства. Заметить что заказ в уравнение здесь, мы вернемся к нему в следующий пост.группа экспертов обсудила различные поддержка нескольких свойств подходы: мы думаем, что уровень класса подход ограничения обеспечивает достаточно простоты и гибкости по сравнению с другим уровнем собственности подходы, включающие зависимости. Ваши отзывы приветствуются.
для правильной работы с Проверка Зернах, в примере, приведенном в ответ можно переписать следующим образом:
@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; } } }
валидатор уровня класса-это путь, когда вы хотите остаться со спецификацией проверки Bean. Если вы рады использовать функцию Hibernate Validator, вы можете использовать @ScriptAssert, что предусмотрено в валидаторе-4.1.0.Окончательный.