1

Java Bean Validation 1.1 (JSR-349) defines annotations like @Future and @Past for validating temporal types, but they only work with java.util.Date and java.util.Calendar out of the box.

I'm using a field of type java.time.LocalDate and would like to mandate that it's in the future, but to do so it looks like I will have to write my own @Future annotation to support this type, which is a shame because @javax.validation.constraints.Future is semantically ideal.

Given the enhanced options now available in BV 1.1, is it possible to configure the validator to use the existing @javax.validation.constraints.Future annotation with a custom ConstraintValidator that would support the new Java time classes?

EDIT

Ideally I am looking to do this entirely in Java code without writing any XML. While the XML-based solution suggested below would be acceptable, I'd rather not use XML if I can help it.

ATG
  • 1,679
  • 14
  • 25

3 Answers3

1

Finally figured this out. Here's the Java version of a custom constraint definition.

HibernateValidatorConfiguration conf = (HibernateValidatorConfiguration) Validation.byDefaultProvider().configure();
conf.addConstraintDefinitionContributor((constraintDefinitionContributionBuilder) -> {
    constraintDefinitionContributionBuilder.constraint(Future.class)
            .validatedBy(MyCustomFutureConstraintValidator.class)
            .includeExistingValidators(true);
});
Validator validator = conf.buildValidatorFactory().getValidator();
ATG
  • 1,679
  • 14
  • 25
0

In going through the XML deployment descriptor (validation.xml) you can do this:

<constraint-definition annotation="javax.validation.constraints.Future">
        <validated-by include-existing-validators="true">
            <value>com.acme.app.constraint.FutureValidatorForLocalDate</value>
        </validated-by>
</constraint-definition>

This is explained in section 8.1.2 of the specification.

Franck
  • 1,754
  • 1
  • 13
  • 14
  • Thanks, Franck. I should've said I was hoping for a pure Java configuration but this will hopefully point me in the right direction. – ATG Sep 17 '15 at 12:30
  • 1
    If you use the Hibertnate Validator implementation take a look at HibernateValidatorConfiguration for a fluent configuration API. This is a provider specific feature and not compatible with the standard API. http://docs.jboss.org/hibernate/validator/5.2/api/org/hibernate/validator/HibernateValidatorConfiguration.html http://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html/validator-specifics.html – matthias Sep 17 '15 at 14:02
  • Thanks, I'm looking into it. I sense that `ConstraintDef` and `ConstraintMapping` are the way to go but it's not the most intuitive of APIs! – ATG Sep 17 '15 at 14:33
  • Is there any reason why you would prefer adding non-standard & non-intuitive code rather than using standard XML? – Franck Sep 17 '15 at 17:17
  • Compile-time verification, type safety, brevity etc. The usual reasons to favour Java configuration over XML configuration, really! Non-standard is a pill I'm prepared to swallow as I'm not realistically going to switch from Hibernate validator for this. Thanks for your answer, though, it's definitely pointed me towards my solution. – ATG Sep 17 '15 at 17:23
  • In this particular case I don't understand the trade-off, I think it's more dogmatic than pragmatic. You said that you're not going to move away from hibernate-validator but what if you move away from your application server? Anyway glad to help.... – Franck Sep 17 '15 at 17:29
  • Well, we'll agree to disagree, then. At least future visitors to this question can see both methods now! – ATG Sep 17 '15 at 17:31
-1

The provided solutions via the Configuration instance or via XML are correct. It is also correct that LocalDate cannot be validated out of the box. However, I disagree that @Future is indeed semantically ideal for this date type. Whether something is in the future can only be answered in the case where you have an instance on the timeline. This is not the case with LocalDate. The Javadoc is quite clear about this. There is no time zone information associated with LocalDate. For this reason you cannot tell whether it is in the future or past. See also - http://in.relation.to/2015/07/30/hibernate-validator-521-final/

Hardy
  • 18,659
  • 3
  • 49
  • 65