作业批改系统热力图不显示问题排查记录
问题现象
教学数据仪表盘中的「知识点掌握度热力图」区域空白,不显示任何数据。浏览器控制台显示接口返回 500 错误。
排查过程
第一步:确认数据链路
首先检查后端的 HomeworkKnowledgeMapper,发现 SQL 查询逻辑是正确的:
- 从
homework_knowledge表查询知识点掌握记录 - JOIN
homework_evaluation表按班级筛选 - 按知识点分组计算平均掌握度
数据流设计没有问题,直接查询批改结果表,避免了知识点名称映射的混乱。
第二步:定位后端异常
查看后端日志,发现具体的错误信息:
1 | java.lang.ClassCastException: class java.math.BigDecimal cannot be cast to class java.lang.Double |
错误发生在 DashboardServiceImpl.java 第 121 行。
第三步:分析根因
问题出在类型转换上:
1 | // 原代码 |
PostgreSQL 的 AVG() 函数返回的是 BigDecimal 类型,而不是 Double。直接使用强制类型转换会抛出 ClassCastException。
这是不同数据库之间的差异:
| 数据库 | AVG() 返回类型 |
|---|---|
| MySQL | Double / Long |
| PostgreSQL | BigDecimal |
| Oracle | BigDecimal |
解决方案
修改 DashboardServiceImpl.java 中的类型处理逻辑:
1 | // 修复后的代码 |
使用 Number 接口作为中间层,可以兼容 BigDecimal、Double、Float 等各种数值类型。
经验总结
1. 数据库兼容性注意点
当使用聚合函数(AVG()、SUM()、COUNT() 等)时,不同数据库的返回类型可能不同。编写跨数据库兼容的代码时,需要特别注意这一点。
2. 防御性编程
处理数据库查询结果时,避免直接强制类型转换:
1 | // ❌ 不推荐 - 可能抛出 ClassCastException |
3. 日志的重要性
如果没有后端详细的异常堆栈,这个问题很难定位。生产环境务必开启完整的日志记录,包括:
- SQL 执行日志
- 异常堆栈信息
- 请求/响应参数
最终效果
修复后热力图正常显示,按掌握度从低到高排序,颜色区分:
- 🔴 红色:掌握度 < 60%(薄弱)
- 🟡 黄色:掌握度 60%-80%(一般)
- 🟢 绿色:掌握度 > 80%(良好)
技术栈
- 后端: Spring Boot + MyBatis-Plus + PostgreSQL
- 前端: Vue 3
- 问题类型: 数据库类型兼容性问题
- 修复耗时: 10 分钟
本文首发于个人博客,转载请注明出处。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 LKL-ZREO!




