调用SqlSession的各种方法报错排查(Error xxx . Cause: xxx)

当调用SqlSession的方法,偶尔出现一些Error xxx . Cause: xxx,这种异常信息难以看出来是哪里引起的问题,而SqlSession有三个实现类(SqlSessionTemplate,SqlSessionManager,DefaultSqlSession);

下面会展示这三个类的底层代码封装的异常信息,以便于我们排查,(当出现下列报错,大多数是配置问题)

具体排查问题的过程可以参照:
mybatis批量更新(BATCH)报空指针异常(Error committing transaction. Cause:NullPointerException)-CSDN博客

大部分都进入的默认的实现类DefaultSqlSession,其中所有报错信息如下:

1.  Expected one result (or null) to be returned by selectOne(), but found:
对应方法->selectOne(String statement, Object parameter)

2.  Error querying database. Cause:
对应方法->selectCursor(String statement, Object parameter, RowBounds rowBounds);

对应方法->selectList(String statement, Object parameter, RowBounds rowBounds);

对应方法->select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);

3. Error updating database. Cause:
对应方法->update(String statement, Object parameter)

4. Error committing transaction. Cause:
对应方法->commit(boolean force)

5. Error rolling back transaction. Cause:

对应方法->rollback(boolean force)

6. Error flushing statements. Cause:

对应方法->flushStatements()

7. Error closing cursor. Cause:

对应方法->closeCursors()

8. Error getting a new connection. Cause:

对应方法->getConnection()

其余两个类没有罗列出来,大家可以自己进入类中搜索一下~

<think>嗯,用户提供的日志信息涉及到MyBatis和Spring事务管理,出现了一个UnsupportedOperationException异常。我需要先理解这些日志的含义,然后找出可能的原因,最后给出解决方案。 首先,日志中提到了创建新的SqlSession,注册事务同步,释放SqlSession,以及事务同步注销和关闭SqlSession。这些步骤看起来是MyBatis在Spring管理的事务中正常处理SqlSession生命周期的过程。但随后出现了错误,导致PersistenceException,原因是UnsupportedOperationException。 接下来,我需要考虑可能引发UnsupportedOperationException的情况。这个异常通常发生在调用不支持的方法时,比如尝试修改一个不可变的集合。例如,使用Arrays.asList()创建的List是不可变的,如果尝试添加或删除元素,就会抛出这个异常。因此,用户可能在查询结果处理中,不小心尝试修改了一个不可变的集合。 另外,Mapper接口或XML配置错误也可能导致问题。如果Mapper接口定义的方法与XML中的SQL语句不匹配,或者返回类型不正确,例如返回了一个基本类型但实际结果返回了多个值,也可能引发异常。此外,MyBatis版本与Spring的兼容性问题也可能导致类似错误,但相对较少见。 用户需要检查他们的代码,特别是在处理数据库查询结果的部分,查看是否有对不可变集合的修改操作。同时,核对Mapper接口和XML的配置,确保方法签名和返回类型正确。另外,检查MyBatis和Spring的版本兼容性也是必要的步骤。如果问题依旧,可以增加MyBatis的日志级别,获取更详细的错误信息,帮助定位问题所在。</think>在MyBatis与Spring整合的框架中,关于`SqlSession`和事务同步的日志信息及错误分析如下: --- ### 一、日志流程解析 1. **创建SqlSession** $$ \text{Creating\ new\ SqlSession} $$ - MyBatis通过`SqlSessionFactory`创建新的数据库会话,这是执行SQL操作的基础单元 2. **事务同步注册** $$ \text{Registering\ transaction\ synchronization} $$ - Spring将当前SqlSession绑定到事务管理器,实现事务上下文管理 - 特征:同一个事务中复用相同SqlSession(通过`org.apache.ibatis.session.defaults.DefaultSqlSession@3a33816e`哈希值可确认) 3. **资源释放与注销** ```log Releasing transactional SqlSession Transaction synchronization deregistering/closing ``` - 事务完成后,Spring按顺序释放资源:解除绑定 > 关闭连接 > 清理线程上下文 --- ### 二、错误原因分析 #### 关键错误线索 ```log UnsupportedOperationException MyBatisSystemException: Error querying database ``` #### 常见触发场景 1. **不可变集合操作** ```java // 示例:Arrays.asList()返回不可修改的List List<Post> posts = Arrays.asList(sqlSession.selectList(...)); posts.add(new Post()); // 抛出UnsupportedOperationException ``` 2. **Mapper配置问题** - XML映射文件中存在未实现的SQL方法 - 返回类型不匹配(如声明返回`List`但实际返回单个对象) 3. **MyBatis版本冲突** - Spring Boot与MyBatis版本不兼容(常见于3.x与2.x跨大版本) --- ### 三、排查步骤建议 1. **定位堆栈源头** ```log PostController.getPostPage.error // 定位到Controller层调用点 ``` - 检查DAO层方法`getPostPage`的具体实现 2. **检查结果集处理** ```java // 典型问题代码示例 public List<Post> getPosts() { return Collections.unmodifiableList(sqlSession.selectList(...)); } // 后续代码尝试修改该List时崩溃 ``` 3. **验证Mapper配置** ```xml <!-- 检查XML映射是否匹配 --> <select id="getPostPage" resultType="com.example.Post"> SELECT * FROM posts WHERE is_deleted = 0 </select> ``` - 确认`resultType`与Java类型完全匹配 - 检查是否存在未实现的`<insert>/<update>`占位符 4. **依赖版本验证** ```gradle // 推荐版本组合(Spring Boot 2.7.x) implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1' ``` --- ### 四、解决方案 1. **防御性集合拷贝** ```java // 替换不可变集合为可修改实现 new ArrayList<>(sqlSession.selectList(...)); ``` 2. **启用完整堆栈日志** ```properties # application.properties logging.level.com.os.mapper=TRACE mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` 3. **事务注解检查** ```java @Transactional(rollbackFor = Exception.class) public Page<Post> getPostPage() { // 确保事务方法内没有跨线程操作 } ``` --- 通过以上分析,建议优先排查**结果集处理中对不可变集合的修改操作**,这是该异常的最常见触发场景。如果问题仍未解决,可提供Mapper接口定义和XML片段进一步分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值