编辑 | blame | 历史 | 原始文档

任务车辆关联插入问题修复说明

问题描述

在新增任务车辆关联时出现以下错误:
### Error updating database. Cause: java.sql.SQLException: Field 'assign_time' doesn't have a default value ### ### The error may exist in file [SysTaskVehicleMapper.xml] ### ### The error may involve com.ruoyi.system.mapper.SysTaskVehicleMapper.insertSysTaskVehicle-Inline ### ### The error occurred while setting parameters ### ### SQL: insert into sys_task_vehicle ( task_id, vehicle_id, status ) values ( ?, ?, ? ) ###

问题原因

  1. 数据库表结构约束sys_task_vehicle 表中的 assign_timeassign_by 字段定义为 NOT NULL
  2. Service层缺失insertSysTaskVehicle 方法没有设置这些必需字段的值
  3. Mapper层条件判断:XML中的插入语句只有在字段不为null时才包含这些字段

修复方案

1. Service层修复

文件SysTaskVehicleServiceImpl.java

修复内容
java @Override @Transactional public int insertSysTaskVehicle(SysTaskVehicle sysTaskVehicle) { // 设置分配时间和分配人 if (sysTaskVehicle.getAssignTime() == null) { sysTaskVehicle.setAssignTime(DateUtils.getNowDate()); } if (sysTaskVehicle.getAssignBy() == null || sysTaskVehicle.getAssignBy().isEmpty()) { sysTaskVehicle.setAssignBy(SecurityUtils.getUsername()); } // 设置默认状态 if (sysTaskVehicle.getStatus() == null || sysTaskVehicle.getStatus().isEmpty()) { sysTaskVehicle.setStatus("ASSIGNED"); } sysTaskVehicle.setCreateTime(DateUtils.getNowDate()); return sysTaskVehicleMapper.insertSysTaskVehicle(sysTaskVehicle); }

修复说明
- 自动设置 assignTime 为当前时间
- 自动设置 assignBy 为当前登录用户
- 自动设置 status 为 'ASSIGNED'(如果未设置)
- 确保所有必需字段都有值

2. Mapper层修复

文件SysTaskVehicleMapper.xml

修复前
xml <insert id="insertSysTaskVehicle" parameterType="SysTaskVehicle" useGeneratedKeys="true" keyProperty="id"> insert into sys_task_vehicle <trim prefix="(" suffix=")" suffixOverrides=","> <if test="taskId != null">task_id,</if> <if test="vehicleId != null">vehicle_id,</if> <if test="assignTime != null">assign_time,</if> <if test="assignBy != null and assignBy != ''">assign_by,</if> <if test="status != null and status != ''">status,</if> <if test="remark != null">remark,</if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="taskId != null">#{taskId},</if> <if test="vehicleId != null">#{vehicleId},</if> <if test="assignTime != null">#{assignTime},</if> <if test="assignBy != null and assignBy != ''">#{assignBy},</if> <if test="status != null and status != ''">#{status},</if> <if test="remark != null">#{remark},</if> </trim> </insert>

修复后
xml <insert id="insertSysTaskVehicle" parameterType="SysTaskVehicle" useGeneratedKeys="true" keyProperty="id"> insert into sys_task_vehicle <trim prefix="(" suffix=")" suffixOverrides=","> <if test="taskId != null">task_id,</if> <if test="vehicleId != null">vehicle_id,</if> assign_time, assign_by, <if test="status != null and status != ''">status,</if> <if test="remark != null">remark,</if> </trim> <trim prefix="values (" suffix=")" suffixOverrides=","> <if test="taskId != null">#{taskId},</if> <if test="vehicleId != null">#{vehicleId},</if> #{assignTime}, #{assignBy}, <if test="status != null and status != ''">#{status},</if> <if test="remark != null">#{remark},</if> </trim> </insert>

修复说明
- assign_timeassign_by 字段总是被包含在插入语句中
- 不再使用条件判断,因为这些字段是必需的
- 确保数据库约束得到满足

数据库表结构

CREATE TABLE sys_task_vehicle (
    id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '关联ID',
    task_id BIGINT NOT NULL COMMENT '任务ID',
    vehicle_id BIGINT NOT NULL COMMENT '车辆ID',
    assign_time DATETIME NOT NULL  COMMENT '分配时间',  -- NOT NULL 约束
    assign_by VARCHAR(64) NOT NULL COMMENT '分配人',    -- NOT NULL 约束
    status VARCHAR(20) DEFAULT 'ASSIGNED' COMMENT '关联状态',
    remark VARCHAR(500) COMMENT '备注',
    
    UNIQUE KEY uk_task_vehicle (task_id, vehicle_id),
    FOREIGN KEY (task_id) REFERENCES sys_task(task_id) ON DELETE CASCADE,
    FOREIGN KEY (vehicle_id) REFERENCES tb_vehicle_info(vehicle_id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='任务车辆关联表';

修复效果

修复前

  • ❌ 插入时缺少必需字段值
  • ❌ 数据库约束违反
  • ❌ 出现 "Field doesn't have a default value" 错误

修复后

  • ✅ 自动设置所有必需字段
  • ✅ 满足数据库约束
  • ✅ 插入操作成功
  • ✅ 数据完整性得到保证

测试验证

1. 单元测试

@Test
public void testInsertSysTaskVehicle() {
    SysTaskVehicle taskVehicle = new SysTaskVehicle();
    taskVehicle.setTaskId(1L);
    taskVehicle.setVehicleId(1L);
    // 不设置 assignTime, assignBy, status
    
    int result = sysTaskVehicleService.insertSysTaskVehicle(taskVehicle);
    
    assertThat(result).isEqualTo(1);
    // 验证自动设置的字段
    assertThat(taskVehicle.getAssignTime()).isNotNull();
    assertThat(taskVehicle.getAssignBy()).isEqualTo("admin");
    assertThat(taskVehicle.getStatus()).isEqualTo("ASSIGNED");
}

2. 集成测试

-- 测试插入
INSERT INTO sys_task_vehicle (task_id, vehicle_id, assign_time, assign_by, status) 
VALUES (1, 1, NOW(), 'admin', 'ASSIGNED');

-- 验证结果
SELECT * FROM sys_task_vehicle WHERE task_id = 1 AND vehicle_id = 1;

注意事项

  1. 数据一致性:确保 assign_timeassign_by 字段始终有值
  2. 用户上下文assign_by 字段依赖当前登录用户,需要确保用户已登录
  3. 时间同步assign_time 使用服务器时间,确保时间同步
  4. 状态管理:默认状态为 'ASSIGNED',可根据业务需求调整

相关文件

  • SysTaskVehicleServiceImpl.java - Service层实现
  • SysTaskVehicleMapper.xml - MyBatis映射文件
  • sys_task_vehicle - 数据库表
  • SysTaskVehicle.java - 实体类

后续优化建议

  1. 字段验证:在实体类中添加字段验证注解
  2. 异常处理:添加更详细的异常处理机制
  3. 日志记录:记录分配操作的详细日志
  4. 权限控制:确保只有有权限的用户才能分配车辆
  5. 数据审计:记录所有分配操作的审计信息