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 null
válidos en caso contrario.
¿Cómo puedo realizar este tipo de validación con JPA 2.0 / Hibernate? Con una @NotNull
anotació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
TYPE
yRUNTIME
debe reemplazarse porElementType.TYPE
yRetentionPolicy.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
isoA2Code
está almacenado en laCountry
tabla DB . ¿Es una buena idea hacer una llamada DB desde aquí? Además, me gustaría vincularlos después de la validación porqueAddress
belongs_to
aCountry
y quiero que laaddress
entrada tengacountry
la clave externa de la tabla. ¿Cómo vincularía el país a la dirección?@ValidAddress
anotació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