在进行修改测试的时候报了个大长错。这里就不全贴在这里了因为太长了,我提取了所有主要信息供参考:
1. 顶层调用异常:
org.apache.dubbo.rpc.RpcException: Failed to invoke the method updateAdminRole in the service com.moriha.common.service.AdminService. Tried 3 times of the providers [192.168.126.1:20882] (1/1)
from the registry 192.168.0.99:8848 on the consumer 192.168.126.1 using the dubbo version 3.2.4.
Last error is: Failed to invoke remote method: updateAdminRole
2. 中间包装异常
Caused by: org.apache.dubbo.remoting.RemotingException: java.io.IOException: org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: autotype not support : org.springframework.jdbc.UncategorizedSQLException
3. 根因异常
Caused by: com.alibaba.fastjson2.JSONException: autotype not support : org.springframework.jdbc.UncategorizedSQLException
报错解释:
- RpcException: Failed to invoke the method updateAdminRole Dubbo 消费者调用远程接口updateAdminRole方法失败,已重试 3 次服务提供者依旧失败。
- RemotingException Dubbo 网络通信层出现异常,服务端向客户端回传数据时 IO 异常。
- SerializationException Dubbo 序列化环节出错,使用 FastJson2 序列化数据失败。
- fastjson2.JSONException: autotype not support : UncategorizedSQLException FastJson2 默认关闭自动类型解析(autotype)安全机制,无法对 Spring 数据库通用异常UncategorizedSQLException进行序列化、反序列化;服务端数据库报错后,异常实例无法序列化传回调用方,直接打断 RPC 调用。
这个的意思总结一下就是:【提供者端(shopping_admin_service)执行 SQL 时抛出了 UncategorizedSQLException,然后 Dubbo 尝试用 fastjson2 序列化这个异常对象时失败了。】
核心字段: UncategorizedSQLException 是 Spring 对 MyBatis、JDBC 所有无法归类的数据库底层异常的统一封装类,只要出现这个异常类名,就代表服务端 SQL 执行、数据库操作直接报错了。
层级关系: 数据库 SQL 异常→抛出 UncategorizedSQLException→FastJson2 无法序列化该异常→触发 SerializationException 序列化异常→产生 RemotingException 网络 IO 返回异常→最终外层包装 RpcException 远程调用失败。
所以可以想到产生的原因大概是:
- Dubbo 选用 FastJson2 做序列化,未开启 autotype 白名单,复杂异常类无法序列化传输;
- 服务端异常序列化失败,网络响应数据构造失败,触发 Dubbo 底层 RemotingException 通信异常;
- 远程接口多次重试依旧无法正常返回结果,Dubbo 外层包装为 RpcException 调用失败异常。
根因是 SQL 参数错误抛出数据库异常,才触发序列化失败
经过我的排查发现:
我写的 addRoleToAdmin 方法的参数是 Long[] rids(数组),但 XML 中直接用了 #{rid}
XML 未使用 foreach 遍历直接取值,SQL 参数绑定错误触发数据库异常,进而连锁引发 2、3、4 号上层框架异常。
我没有实现数组遍历导致了这个报错。为了更直观好理解,我把问题代码粘在这里:
// … existing code …
//给管理员添加角色 (我写成了Long[] rids 而非现在这样)
void addRoleToAdmin(@Param("aid") Long aid, @Param("rid") Long rid);
}
// … existing code …
@Override
public void updateAdminRole(Long aid, Long[] rids) {
// 删除管理员所有角色
adminMapper.deleteAdminAllRole(aid);
// 重新添加管理员角色
for (Long rid : rids) {
// 因为刚才的失误,这里允许写成 new Long[] rids
adminMapper.addRoleToAdmin(aid, rid);
}
}
// … existing code …
改动说明:
- AdminMapper.java:Long[] rids → Long rid,改为接收单个角色 ID
- AdminServiceImpl.java:new Long[]{rid} → rid,循环中直接传单个值
这样 XML 中的 #{rid} 就能正确绑定到单个 Long 值了,SQL 不再报错。
网硕互联帮助中心






评论前必须登录!
注册