为啥 Spring Sql 会丢失对 H2DB 异常的跟踪并引发 NoClassDefFounderror 异常

Posted

技术标签:

【中文标题】为啥 Spring Sql 会丢失对 H2DB 异常的跟踪并引发 NoClassDefFounderror 异常【英文标题】:why would Spring Sql loose track of H2DB Exceptions and raise a NoClassDefFound Exception为什么 Spring Sql 会丢失对 H2DB 异常的跟踪并引发 NoClassDefFounderror 异常 【发布时间】:2016-07-07 13:51:39 【问题描述】:

我在生产中使用 mysql 数据库和用于 Junit 测试的嵌入式 H2 数据库。 在我的 Dao 代码类中访问我的数据库是通过

@Autowired
private JdbcTemplate userDBJdbcTemplate;

对数据库的实际调用是通过userDBJdbcTemplate.update(...) 调用完成的。

我的 Junit 测试用例使用适当的配置文件子类化一个抽象类,该配置文件可以正确地自动装配 H2 基础

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes =  ... )
@ActiveProfiles("database-test")
public abstract class H2DBTests 

这一切正常,但是当我在 Sql 查询或语句中进行糟糕的编码工作时,userDBJdbcTemplate.update(...) 将失败但异常的最初原因(例如在某些情况下忘记为列添加 ps.setxxx例如...)在此过程中丢失。我最终得到一个 java.lang.NoClassDefFoundError 信息丢失。

更准确地说,原因异常是在org.springframework.jdbc.core.JdbcTemplate 类中引发的。例如这里一个

org.h2.jdbc.JdbcSQLException: Parameter "#5" is not set

正确地引发了异常,该异常在稍后的 org.springframework.jdbc.core.JdbcTemplate 类中的此调用中的某处丢失:

throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex);

当我回到我的代码中时,我得到一个java.lang.NoClassDefFoundError: org/springframework/dao/QueryTimeoutException,根本没有引用 ps 设置中缺少的参数。

【问题讨论】:

QueryTimeoutExceptionspring-tx-X.X.X.jar 文件中。您的类路径中似乎缺少该 jar 文件。 谢谢。我是否缺少来自 maven 的依赖项之一?目前作为 maven 依赖 spring-core、spring-context、spring-jdbc、spring-test 奇怪的是,Query Time out 异常与真正引发的真正的 org.h2 异常无关。它必须在spring sql异常翻译过程中的某个地方设置,我有问题要精确遵循...... Maven名和jar文件名一样,所以添加maven依赖spring-tx。您的实际异常可能不会映射到 QueryTimeoutException,但 spring sql 异常翻译代码可能仍需要该类存在,因此添加依赖项并查看是否使一切正常。 仅供参考:spring-jdbc 应该为您拉入spring-tx。根据我的 Gradle 构建脚本,至少在 4.2.6 中是这样。 【参考方案1】:

@Andreas 导致了正确的原因:Spring 项目依赖项配置错误。正确翻译异常所需的 spring-tx 模块位于 3.0.6 版本中,而我的 spring-core 和 spring-jdbc 位于 4.2.6 版本中。

项目的另一部分是使用带有 1.3.2 版本的 spring ldap,它正在拉取 spring-tx 3.0.6。为了保留使用 1.3.2 spring ldap 版本,正确的解决方案是在 spring-ldap 部分添加 spring-tx 的排除。

这是使一切正常的 pom.xml 的修改版本:

    <dependency>
        <groupId>org.springframework.ldap</groupId>
        <artifactId>spring-ldap-core</artifactId>
        <version>$org.springframework.ldap-version</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

【讨论】:

以上是关于为啥 Spring Sql 会丢失对 H2DB 异常的跟踪并引发 NoClassDefFounderror 异常的主要内容,如果未能解决你的问题,请参考以下文章

为啥 import.sql 在 Spring Boot 中会失败?

AbstractApplicationContext(Spring)下refresh()方法的用途是啥?为啥使用 refresh() 后 bean 单例范围丢失?

为啥 UITableView 在同时滚动和更新时会丢失部分标题?

为啥 spring-boot-starter-jdbc 会破坏我的 REST 端点?

java float double精度为啥会丢失

JavaScript为啥浮点数会丢失精度