【问题标题】:Issues with Hibernate Validator after upgrading from Hibernate 3 to 4 with Spring 4使用 Spring 4 从 Hibernate 3 升级到 4 后出现 Hibernate Validator 问题
【发布时间】:2017-04-05 07:24:02
【问题描述】:

使用 Spring 4 从 Hibernate 3 升级到 4 后 Hibernate Validator 出现问题

我接手了一个非常古老的 Java 项目(富客户端、swing、hibernate 3),它具有某种本土的依赖注入,使用 Hibernate 3,并且具有手动事务管理。这意味着每个怪异的 DAO 方法都会获得一个布尔值来触发会话是否打开。当您在许多地方触摸那个脆弱的构造时,您可以想象这意味着什么……无论如何,我不是来抱怨的……这是我的问题:

我必须实现一个新的复杂功能,并且很快意识到整个手动事务已经失控,我可以说服客户重构整个事情以使用 Spring transaction mgmt 和 hibernate 4。

所以我开始实施这个,在遇到一些重大问题之后,现在整个事情都运行了,但有一些更详细的小问题。

让我抓狂的是Hibernate Validator。我猜现有的实现是老式的方式。所有实体类都派生自一个名为 DomainObject 的类,该类包含项目中存在的所有实体的org.hibernate.validator.ClassValidator。 在实体本身中,将使用 .InvalidValues() 调用此验证器以验证字段。

自从我使用 Spring 4.2.4.RELEASE 升级到 Hibernate-Core 4.3.6.Final 后,我在验证实体时遇到了很多问题。我知道我使用的是旧的验证器版本,但是当我升级到更高版本时,整个项目会出现无数错误,例如The type org.hibernate.validator.InvalidValue cannot be resolved. It is indirectly referenced from required .class files,但我无法通过我在 SO 上找到的所有答案来解决这个问题。

现在导致错误的验证在 SwingWorker Thread 中运行,在调试它时,我可以看到异常在 Spring 深处被吞没了,我什至没有得到堆栈跟踪 :-( 我认为问题仍然来自休眠依赖项的错误组合,但我真的很绝望,直到我得到了一些可以一起工作的东西 你可以在下面的 pom.xml sn-p 中看到。

这里是 sn-ps

<!-- Hibernate Stuff -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.6.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.5.6-Final</version>
    <!-- Hibernate Core needs a higher version so we exclude this one -->
        <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-commons-annotations</artifactId>
                <version>3.2.0.Final</version>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.hibernate.javax.persistence</groupId>
        <artifactId>hibernate-jpa-2.0-api</artifactId>
        <version>1.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.2.Final</version>
    </dependency>
<!--        <dependency> -->
<!--            <groupId>org.hibernate</groupId> -->
<!--            <artifactId>hibernate-c3p0</artifactId> -->
<!--            <version>3.6.10.Final</version> -->
<!--        </dependency> -->
<!--        <dependency> -->
<!--            <groupId>javassist</groupId> -->
<!--            <artifactId>javassist</artifactId> -->
<!--            <version>3.12.0.GA</version> -->
<!--        </dependency> -->

<!--        <dependency> -->
<!--            <groupId>c3p0</groupId> -->
<!--            <artifactId>c3p0</artifactId> -->
<!--            <version>0.9.1.2</version> -->
<!--        </dependency> -->

这是在验证期间将调用的所有实体中的方法。

 /**
 * validate the entity. This method will be called internally before save or
 * update to check validity before sql statements
 */
@Override
@Transient
protected InvalidValue[] validate(final String fieldName) {
    if (fieldName == null) {
        return VALIDATOR_ASSEMBLY_ENTRY.getInvalidValues(this);
    } else {
        return VALIDATOR_ASSEMBLY_ENTRY.getInvalidValues(this, fieldName);
    }
}

有什么提示吗?如果您需要更多代码,请告诉我。整个 Spring 和 Hibernate 配置都是用 Java 完成的。没有xml。

【问题讨论】:

  • InvalidValue 在 Hibernate Validator 4 及更高版本中不存在,即您必须调整“在验证期间将调用的所有实体中的方法”,以便它使用当前版本的 Hibernate Validator(或者实际上是 Bean Validation,这是 Hibernate Validator 从版本 4 开始实现的规范)。
  • @Gunnar 是的,这就是我的预期。所以我开始(只是看看它是否有帮助)停用所有实体中的每一个验证方法,瞧……现在那些奇怪的错误已经消失了。但是要真正实现 Hibernate Validation,使用版本 4 的注释驱动方式将花费我更多时间:-/。你知道一个关于使用 hibernate 验证器 4 和 spring 的最佳实践的好教程吗?
  • 给其他遇到这个问题的人一个提示:我现在完成了 H-V 的新实现,一个很好的指导是 Thisthat 。基本上 H-V 3 和 4 的实现没有那么不同。我只是没有看到所有自定义验证器都是让我发疯的部分 ;-)

标签: java spring hibernate validation hibernate-validator


【解决方案1】:

我通过一些解决方法解决了这个问题。把它放在你的 pom.xml 中

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator-legacy</artifactId>
    <version>4.0.2.GA</version> 
</dependency>

【讨论】:

  • 感谢您的回答@KimTiagoBaptista。实际上不是依赖关系,而是实现是问题所在。例如。 H-V4 的 validate 方法返回一组 javax.validation.ConstraintViolation&lt;T&gt; 而不是 H-V3 中的 org.hibernate.validator.InvalidValue 数组,但它在上下文方面也是如此。更令人烦恼的是,H-V4 导致了 Spring 事务管理的一些奇怪问题,但这是另一个长篇大论。
最近更新 更多