Estoy usando la validación JPA 2.0 / Hibernate para validar mis modelos. Ahora tengo una situación en la que se debe validar la combinación de dos campos:
public class MyModel {
public Integer getValue1() {
//...
}
public String getValue2() {
//...
}
}
El modelo no es válido si ambos getValue1()y getValue2()son nullválidos en caso contrario.
¿Cómo puedo realizar este tipo de validación con JPA 2.0 / Hibernate? Con una @NotNullanotación simple, ambos captadores deben ser no nulos para pasar la validación.
java
jpa
jpa-2.0
bean-validation
Daniel Rikowski
fuente
fuente

Respuestas:
Para la validación de múltiples propiedades, debe usar restricciones de nivel de clase. De Bean Validation Sneak Peek parte II: restricciones personalizadas :
fuente
TYPEyRUNTIMEdebe reemplazarse porElementType.TYPEyRetentionPolicy.RUNTIME, respectivamente.import static java.lang.annotation.ElementType.*;yimport static java.lang.annotation.RetentionPolicy.*;Para funcionar correctamente con Bean Validation , el ejemplo proporcionado en la respuesta de Pascal Thivent podría reescribirse de la siguiente manera:
@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; } } }fuente
isoA2Codeestá almacenado en laCountrytabla DB . ¿Es una buena idea hacer una llamada DB desde aquí? Además, me gustaría vincularlos después de la validación porqueAddressbelongs_toaCountryy quiero que laaddressentrada tengacountryla clave externa de la tabla. ¿Cómo vincularía el país a la dirección?@ValidAddressanotación en el objeto País, obtendría unaNo validator could be found for constraint 'com.example.validation.ValidAddress' validating type 'com.example.Country'excepción.Un validador de nivel de clase personalizado es el camino a seguir, cuando desea permanecer con la especificación de validación de Bean, ejemplo aquí .
Si está contento de usar una función de Hibernate Validator, puede usar @ScriptAssert , que se proporciona desde Validator-4.1.0.Final. Excepcional de su JavaDoc:
Ejemplo:
@ScriptAssert(lang = "javascript", script = "_this.value1 != null || _this != value2)") public class MyBean { private String value1; private String value2; }fuente