Ошибка: для типа не найден валидатор: java.time.LocalDate

Я работаю над проектом, который использует валидацию bean (Hibernate Validator 5.1.3.Final). Мой bean имеет атрибут с аннотацией @Past.

@Past(message = "A data deve estar no passado.")
private LocalDate dataAbertura;

Но, когда происходит проверка, я получаю следующее исключение:

21:46:12,424 ERROR [io.undertow.request] (default task-35) UT005023: Exception handling request to /financeiro/clientes/pessoafisica: javax.servlet.ServletException: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.time.LocalDate.
    at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:127) [vraptor-4.1.4.jar:]
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166) [undertow-servlet-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:197) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_25]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_25]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_25]
Caused by: javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.time.LocalDate.
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.verifyResolveWasUnique(ConstraintValidatorManager.java:218) [hibernate-validator-5.1.3.Final.jar:5.1.3.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.findMatchingValidatorClass(ConstraintValidatorManager.java:193) [hibernate-validator-5.1.3.Final.jar:5.1.3.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:97) [hibernate-validator-5.1.3.Final.jar:5.1.3.Final]
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125) [hibernate-validator-5.1.3.Final.jar:5.1.3.Final]

Что случилось? Hibernate Validator не поддерживает LocalDate?

Ответ 1

На самом деле проблема для ссылки - HV-874. Hibernate Validator 5.2.x добавляет поддержку некоторых новых типов даты и времени Java 8. В этом контексте я должен подчеркнуть "некоторые". В частности, LocalDate не поддерживается. Javadocs LocalDate говорит:

Этот класс не сохраняет или не представляет собой временную или временную зону. Вместо, это описание даты, используемой для дней рождения. Это не может представляют собой мгновение на временной линии без дополнительной информации таких как смещение или временная зона.

Без единого момента на временной шкале невозможно сказать, присутствует ли данная дата в части или будущем. Сначала, установив часовой пояс, можно было бы ответить на этот вопрос и ответить на него.

Если вы по-прежнему считаете, что в вашем случае использовать смысл Past и @Future для LocalDate, вы всегда можете реализовать свой собственный ConstraintValidator для LocalDate и зарегистрировать его через XML, используя constraint-definition в файле сопоставления ограничений, как показано здесь.

Если вы используете Hibernate Validator 5.2, вы также можете использовать подход Java ServiceLoader для регистрации дополнительных реализаций ConstraintValidator - см. ConstraintDefinitionContributor. Последняя на данный момент является особенностью валидатора Hibernate.

Ответ 2

Так как LocalDate все еще довольно много, многие библиотеки еще не справляются с этим. В проекте, над которым я работаю, мне пришлось писать пользовательский тип для LocalDate.

Взгляните на эту проблему спящего режима HHH-8844

Похоже, что они добавили новый модуль hibernate-java8 для поддержки java 8 новых API даты.

Я знаю, что приведенная выше информация говорит о сопоставлении типов, но то же самое может быть справедливо для проверки.

Если нет готового решения, вам просто нужно написать свой собственный. См. Следующую страницу для примера добавления летчиков проверки joda, java 8 дат должны быть похожими ссылка