Я использую проверку JPA 2.0 / Hibernate для проверки моих моделей. Теперь у меня ситуация, когда необходимо проверить комбинацию двух полей:
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
Модель недействительна, если они оба getValue1()
и getValue2()
, null
и действительны в противном случае.
Как я могу выполнить такую проверку с помощью JPA 2.0 / Hibernate? Для простой @NotNull
аннотации оба метода получения должны быть ненулевыми, чтобы пройти проверку.
java
jpa
jpa-2.0
bean-validation
Даниэль Риковски
источник
источник
Ответы:
Для проверки нескольких свойств следует использовать ограничения на уровне класса. Из Bean Validation Sneak Peek, часть II: настраиваемые ограничения :
источник
TYPE
иRUNTIME
следует заменить наElementType.TYPE
иRetentionPolicy.RUNTIME
соответственно.import static java.lang.annotation.ElementType.*;
иimport static java.lang.annotation.RetentionPolicy.*;
Чтобы правильно работать с Bean Validation , пример, приведенный в ответе Pascal Thivent, можно переписать следующим образом:
@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; } } }
источник
isoA2Code
хранится вCountry
таблице БД . Это хорошая идея сделать отсюда вызов БД? Кроме того, я хотел бы связать их после проверки, потому чтоAddress
belongs_to
aCountry
и я хочу, чтобыaddress
запись имелаcountry
внешний ключ таблицы. Как мне связать страну с адресом?@ValidAddress
аннотацию для объекта Country, вы получитеNo validator could be found for constraint 'com.example.validation.ValidAddress' validating type 'com.example.Country'
исключение.Пользовательский валидатор уровня класса - это то, что вам нужно, если вы хотите остаться со спецификацией Bean Validation, например здесь .
Если вы счастливы использовать функцию Hibernate Validator, вы можете использовать @ScriptAssert , который предоставляется с Validator-4.1.0.Final. Exceprt из своего JavaDoc:
Пример:
@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)") public class MyBean { private String value1; private String value2; }
источник