0

Supose we have an object that extends another and I want to create a custom validation for both, example: Period and PeriodAmount objects. Where Period is:

public class Period {
    private LocalDate startDate;
    private LocalDate endDate;

And PeriodAmount is:

public class PeriodAmount extends Period {
    private BigDecimal amount;

I have a custom validator for Period, like this:

    public class PeriodValidator implements ConstraintValidator<ValidPeriod, Period> {

    @Override
    public boolean isValid(Period period, ConstraintValidatorContext context) {
        LocalDate startDate = period.getStartDate();
        LocalDate endDate = period.getEndDate();

        if (startDate == null) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.start.date.null}").addConstraintViolation();
            return false;
        }
        if (endDate != null && startDate.isAfter(endDate)) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.end.date.value}").addConstraintViolation();
            return false;
        }
        return true;
    }

}

This is working perfect for Period. But now I want a custom validator for PeriodAmount and I want to reuse the code that I already have for Period validation. How can I do this in order to call only one validation and have everything validated:

@ValidPeriodAmount
private PeriodAmount periodAmount;
jfajunior
  • 1,211
  • 1
  • 15
  • 19

2 Answers2

0

You could possibly do this more simply without the custom validator:

public class Period {
    @NotNull
    private LocalDate startDate;

    private LocalDate endDate;

    @AssertTrue
    public boolean isValid(){
        return endDate == null || endDate.isAfter(startDate);
    }
}

public class PeriodAmount extends Period{

    @AssertTrue
    public boolean isValid(){
        return super.isValid() && //some other condition
    }
}
Alan Hay
  • 22,665
  • 4
  • 56
  • 110
  • Thanks for your answer Alan. I had this working in much a similar way as your example, but my study now is in the Custom Validator. I really want to see it working with hierarchy of objects but I can't figure it out how. – jfajunior Nov 07 '19 at 08:17
0

I got a solution for this. I don't know if this is the best way of doing it or if there is a more elegant way, but it works. Here is what I have:

public class PeriodAmountValidator implements ConstraintValidator<ValidPeriodAmount, PeriodAmount> {


    @Override
    public boolean isValid(PeriodAmount periodAmount, ConstraintValidatorContext context) {
        PeriodValidator validator = new PeriodValidator();
        if (!validator.isValid(periodAmount, context)) {
            return false;
        }

        BigDecimal amount = periodAmount.getAmount();
        if (amount == null) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.amount.null}").addConstraintViolation();
            return false;
        }
        if (amount.intValue() <= 0) {
            context.disableDefaultConstraintViolation();
            context.buildConstraintViolationWithTemplate("{invalid.amount.value}").addConstraintViolation();
            return false;
        }
        return true;
    }


}

Any thoughts are very welcome!

jfajunior
  • 1,211
  • 1
  • 15
  • 19