Estou usando a validação JPA 2.0 / Hibernate para validar meus modelos. Agora tenho uma situação em que a combinação de dois campos deve ser validada:
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
O modelo é inválido se ambos getValue1()
e getValue2()
são null
e válido caso contrário.
Como posso realizar este tipo de validação com JPA 2.0 / Hibernate? Com uma @NotNull
anotação simples, ambos os getters devem ser não nulos para passar na validação.
java
jpa
jpa-2.0
bean-validation
Daniel Rikowski
fonte
fonte
Respostas:
Para validação de várias propriedades, você deve usar restrições de nível de classe. Do Bean Validation Sneak Peek parte II: restrições personalizadas :
fonte
TYPE
eRUNTIME
deve ser substituído porElementType.TYPE
eRetentionPolicy.RUNTIME
, respectivamente.import static java.lang.annotation.ElementType.*;
eimport static java.lang.annotation.RetentionPolicy.*;
Para funcionar corretamente com a validação de feijão , o exemplo fornecido na resposta de Pascal Thivent pode ser reescrito da seguinte forma:
@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; } } }
fonte
isoA2Code
está armazenada naCountry
tabela do banco de dados . É uma boa ideia fazer uma chamada de DB daqui? Além disso, gostaria de vinculá-los após a validação porqueAddress
belongs_to
umCountry
e quero que aaddress
entrada tenhacountry
a chave estrangeira da tabela. Como eu vincularia o país ao endereço?@ValidAddress
anotação no objeto País, você obterá umaNo validator could be found for constraint 'com.example.validation.ValidAddress' validating type 'com.example.Country'
exceção.Um validador de nível de classe customizado é o caminho a percorrer, quando você deseja ficar com a especificação de validação de feijão, exemplo aqui .
Se você quiser usar um recurso do Hibernate Validator, pode usar @ScriptAssert , que é fornecido desde o Validator-4.1.0.Final. Exceto de seu JavaDoc:
Exemplo:
@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)") public class MyBean { private String value1; private String value2; }
fonte