custom jpa validation in spring boot

Using Hibernate Validation API is not as complex as it seems, and for your constraint is a nice solution. However you can get a easier way to define constrains using Hibernate Validator as we have done in one project adding a few classes. Your constraints will look like this:

@Validate(method = "checkBankData", message = "{BankData.invalid.message}")
@Entity
@Table(name = "transaction_receiver")
public class TransactionReceiver implements Serializable, Addressable {

To get this you need to define @Validate annotation and a CustomValidator class.

@Target({ ElementType.TYPE, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CustomValidator.class)
@Documented
/**
 * Annotation to allow custom validation against model classes
 */
public @interface Validate {

  /**
   * Validation message
   */
  String message();

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

  /**
   * Validation method name
   */
  String method() default "";
}


public class CustomValidator implements ConstraintValidator<Validate, BusinessObject> {

  private static Log log = LogFactory.getLog(CustomValidator.class);
  private String validator;


  @Override
  public void initialize(Validate constraintAnnotation) {
    validator = constraintAnnotation.method();
  }

  @Override
  public boolean isValid(BusinessObject bo, ConstraintValidatorContext constraintContext) {
    try {
      return isValidForMethod(bo);
    } catch (Exception e) {
      /* Error durante la ejecución de la condición o del validador */
      log.error("Error validating "+bo, e);
      return false;
    }
  }


  private boolean isValidForMethod(BusinessObject bo) throws Exception {
    Method validatorMethod =  ReflectionUtils.findMethod(bo.getClass(), validator, new Class[] {});
    if (validatorMethod != null) {
      /* Validator call */
      Boolean valid = (Boolean) validatorMethod.invoke(bo);
      return valid != null && valid;
    } else {
      /* Method not found */
      log.error("Validator method not found.");
      return false;
    }
  }

}

This aproach will be nice if you plan to define more constraints. And you can extend it with more features like conditions for validation or adding multiple validations, etc.

Off-topic:

  • Validation has nothing to do with Spring Boot so there is no need to mention it in your question.

  • serialVersionUID = 1L; Is a very bad idea. Use your IDE serialVersionUID generator to fill this field with a value different for 1L.