Files
hzdyjs/docs/变更管理/code-adjust-record-2025-01-26-cw-performance-indicator-field-strategy-fix.md
T
2025-07-30 23:24:43 +08:00

5.3 KiB

绩效指标字段插入策略修复记录

日期: 2025-01-26
操作人员: AI Assistant
模块: 财务项目申报管理 - 绩效指标 (cw_performance_indicator)

📋 问题描述

🚨 错误信息

### Error updating database. Cause: java.sql.SQLException: Field 'application_no' doesn't have a default value 
### The error may exist in org/dromara/cw/mapper/CwPerformanceIndicatorMapper.java (best guess) 
### The error may involve org.dromara.cw.mapper.CwPerformanceIndicatorMapper.insert-Inline 
### The error occurred while setting parameters 
### SQL: INSERT INTO cw_performance_indicator (...) VALUES (...)
### Cause: java.sql.SQLException: Field 'application_no' doesn't have a default value

🔍 根本原因分析

  1. 数据库约束: cw_performance_indicator 表中多个字段设置为 NOT NULL
  2. MyBatis-Plus默认行为: 当字段值为 null 或空字符串时,MyBatis-Plus 默认忽略这些字段
  3. 插入策略缺失: 实体类字段没有明确的插入策略注解
  4. 字段回填问题: 新增申报时 applicationNo 在BO对象中未及时回填

📊 涉及字段

字段名 数据库约束 Java类型 问题状态
application_id NOT NULL Long ❌ 可能被忽略
application_no NOT NULL String ❌ 被忽略导致错误
indicator_type NOT NULL String ❌ 可能被忽略
indicator_type_name NOT NULL String ❌ 可能被忽略
goal_name NOT NULL String ❌ 可能被忽略
target_value NOT NULL String ❌ 可能被忽略
weight_percentage NOT NULL BigDecimal ❌ 可能被忽略

🔧 修复方案

方案选择: 字段插入策略注解 (方案2)

在 CwPerformanceIndicator 实体类中为所有NOT NULL字段添加 @TableField 插入策略注解。

修复优势

  • ✅ 根本性修复: 确保MyBatis-Plus不忽略必需字段
  • ✅ 预防性保护: 避免未来类似问题
  • ✅ 代码清晰: 明确字段的数据完整性要求
  • ✅ 向后兼容: 不影响现有功能

📝 具体修改内容

文件: backend/ruoyi-modules/ruoyi-cw/src/main/java/org/dromara/cw/domain/CwPerformanceIndicator.java

修改前:

private Long applicationId;
private String applicationNo;
private String indicatorType;
private String indicatorTypeName;
private String goalName;
private String targetValue;
private BigDecimal weightPercentage;

修改后:

@TableField(insertStrategy = FieldStrategy.NOT_NULL)
private Long applicationId;

@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String applicationNo;

@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String indicatorType;

@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String indicatorTypeName;

@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String goalName;

@TableField(insertStrategy = FieldStrategy.NOT_EMPTY)
private String targetValue;

@TableField(insertStrategy = FieldStrategy.NOT_NULL)
private BigDecimal weightPercentage;

插入策略说明

  • FieldStrategy.NOT_NULL: 用于非String类型,字段值不为null时才插入
  • FieldStrategy.NOT_EMPTY: 用于String类型,字段值不为null且不为空字符串时才插入

✅ 预期效果

修复前的问题流程:

前端提交数据 → 后端BO → MyBatis-Plus忽略空字段 → 数据库插入失败

修复后的正常流程:

前端提交数据 → 后端BO → MyBatis-Plus强制插入必需字段 → 数据库插入成功

具体改善:

  1. ✅ 解决 application_no 缺失错误
  2. ✅ 确保所有必需字段都会被插入
  3. ✅ 提高数据完整性保障
  4. ✅ 减少类似字段缺失问题

🧪 测试验证

测试场景:

  1. 新增项目申报 → 保存草稿 → 验证绩效指标正常保存
  2. 编辑项目申报 → 修改绩效指标 → 验证更新正常
  3. 提交审批 → 验证完整流程正常

验证要点:

  • ✅ cw_performance_indicator 表数据完整
  • ✅ 所有NOT NULL字段都有值
  • ✅ 前端操作流畅无报错

📋 后续操作

需要手动执行:

  1. 重新编译后端:

    cd backend
    mvn clean compile -pl ruoyi-modules/ruoyi-cw
    
  2. 重启后端服务:

    # 停止现有服务
    ps aux | grep java | grep ruoyi-admin
    kill -9 [进程ID]
    
    # 启动新服务
    mvn spring-boot:run -pl ruoyi-admin
    
  3. 清理前端缓存并测试:

    cd web
    npm run dev
    

🎯 技术要点

MyBatis-Plus 插入策略:

  • DEFAULT: 默认策略,根据全局配置
  • NOT_NULL: 非NULL判断,只对非NULL值插入
  • NOT_EMPTY: 非空判断,只对非空字符串插入
  • IGNORED: 忽略该字段
  • NEVER: 永不插入

最佳实践:

  • 对于数据库NOT NULL约束的字段,实体类应明确插入策略
  • String类型使用 NOT_EMPTY,其他类型使用 NOT_NULL
  • 重要业务字段应避免使用默认策略

✅ 状态: 代码修改完成,待编译测试
🎯 目标: 彻底解决绩效指标保存时的字段缺失问题
📈 价值: 提升系统稳定性和数据完整性