为啥 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 设置中缺少的参数。
【问题讨论】:
QueryTimeoutException
在spring-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 在同时滚动和更新时会丢失部分标题?