20260604-AI-FLOW触发器达梦数据库兼容性修复记录.md 10 KB

AI-FLOW 触发器在达梦数据库上启动报错修复记录

修改日期:2026-06-04

一、问题现象

后端服务启动时,控制台抛出 ERROR 日志,Spring Boot 启动过程被异常打断:

2026-06-04 10:59:55.798 [main] ERROR org.jeecg.modules.airag.flow.service.a.d:78
- [AI-FLOW] 初始化定时触发器任务失败
org.springframework.dao.DataIntegrityViolationException:
### Error querying database.  Cause: dm.jdbc.driver.DMException: -6105
  第1 行附近出现错误: 数据类型不匹配
### The error may exist in org/jeecg/modules/airag/flow/mapper/AiragFlowMapper.java
### The error may involve org.jeecg.modules.airag.flow.mapper.AiragFlowMapper.selectList
### The error occurred while executing a query
### SQL: SELECT id, trigger_cron FROM airag_flow
       WHERE (status = ? AND (trigger_cron IS NOT NULL AND trigger_cron <> ?))
### Cause: dm.jdbc.driver.DMException: -6105 第1 行附近出现错误: 数据类型不匹配

错误链路:

  • org.jeecg.modules.config.a.a.a(AiragScheduledTaskInitListener.java:28) —— Spring 启动事件监听
  • org.jeecg.modules.airag.flow.service.a.d.initCronTasksFromDB(AiragFlowTaskServiceImpl.java:69) —— 拉取启用 cron 的流程
  • com.baomidou.mybatisplus.extension.repository.IRepository.list —— MyBatis-Plus 查询

二、根因分析

2.1 字段类型来源

airag_flow.trigger_cron 字段在 JeecgBoot 官方升级脚本中以 text 类型添加:

  • 文件:jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.1_0__all_upgrade.sql
  • 关键语句:
ALTER TABLE `airag_flow`
    ADD COLUMN `trigger_cron` text NULL COMMENT 'cron定时任务触发器配置JSON' AFTER `metadata`;

2.2 达梦数据库对 text 类型的处理

  • MySQL 中 text 类型可直接与空字符串 '' 进行 <> 比较;
  • 达梦(DM8)数据库中,text 实际映射为 CLOB 大对象类型;
  • 达梦不允许将 CLOB 类型字段直接与空字符串 '' 使用 <> 操作符比较, 否则抛出 -6105 数据类型不匹配 错误。
  • 通过 USER_TAB_COLUMNS 实测当前 airag_flow.trigger_cron DATA_TYPE = TEXT DATA_LENGTH = 2147483647 NULLABLE = Y

2.3 触发 SQL 来源

AiragFlowTaskServiceImpl.initCronTasksFromDB 通过 MyBatis-Plus 的 LambdaQueryWrapper / QueryWrapper 生成 SQL:

wrapper.eq(AiragFlow::getStatus, "enable");
wrapper.isNotNull(AiragFlow::getTriggerCron);
wrapper.ne(AiragFlow::getTriggerCron, "");

最终生成:

SELECT id, trigger_cron FROM airag_flow
WHERE (status = ? AND (trigger_cron IS NOT NULL AND trigger_cron <> ?))

其中 trigger_cron <> ?? 绑定的是空字符串 ''。该 SQL 在达梦上 触发了 CLOB 与空字符串比较的限制。

三、解决方案

3.1 方案选择

由于:

  1. airag.flow 包对应的 AiragFlowTaskServiceImplAiragScheduledTaskInitListenerAiragFlowMapper 属于 JeecgBoot 商业插件,未提供源码(运行时类路径下为 编译后类),无法直接修改业务代码;
  2. MyBatis-Plus 的 ne("", "") 条件生成的 <> '' 属于框架行为, 强行通过 InnerInterceptor 改写 SQL 会增加维护成本与跨库兼容性风险;
  3. trigger_cron 字段用途为 "cron 定时任务触发器配置 JSON", 单条记录体积很小(远小于 2000 字符)。

综合考虑,采用数据库字段类型变更方案:将 trigger_crontext(达梦中实际为 CLOB)变更为 varchar(2000), 使达梦(也兼容 MySQL)都能与空字符串直接比较。

3.2 方案落实 —— 达梦标准变更流程

达梦不允许通过 MODIFY 直接将 TEXT/CLOB 变更为 VARCHAR(实测报 -6160 数据类型的变更无效),需采用"加新列 -> 灌数据 -> 删旧列 -> 重命名"四步走:

-- 1. 新增临时 VARCHAR(2000) 列
ALTER TABLE airag_flow ADD COLUMN trigger_cron_tmp VARCHAR(2000) NULL;
-- 2. 将原 TEXT 数据通过 CAST 灌入临时列
UPDATE airag_flow SET trigger_cron_tmp = CAST(trigger_cron AS VARCHAR(2000));
-- 3. 删除原 TEXT 列
ALTER TABLE airag_flow DROP COLUMN trigger_cron;
-- 4. 将临时列重命名为原列名
ALTER TABLE airag_flow RENAME COLUMN trigger_cron_tmp TO trigger_cron;

3.3 实测修复结果

修复后通过 JDBC 验证:

验证项 修复前 修复后
原报错 SQL:SELECT ... WHERE trigger_cron <> '' 抛出 -6105 数据类型不匹配 正常执行,命中 1 条
trigger_cron = '' 查询 可执行 命中 11 条(数据一致)
trigger_cron IS NULL 查询 可执行 命中 18 条(数据一致)
UPDATE 行数 - 30 行(30 条记录数据完整保留)

备注:经查询 USER_TAB_COLUMNS,修复后 TRIGGER_CRON 在该视图中 数据类型字段仍显示为 TEXT(疑似达梦的元数据延迟或 TEXT 内部 存储为 VARCHAR 的表现),但实际 SQL 行为已完全符合预期, 原报错已消除,业务查询均可正常执行。

3.4 修改文件清单

序号 文件路径 类型 说明
1 .docs/sql/AI-FLOW触发器兼容达梦数据库修复.sql 新增 达梦数据库手动修复 SQL(4 步变更流程 + 验证步骤)
2 .docs/20260604-AI-FLOW触发器达梦数据库兼容性修复记录.md 新增 本开发记录文档

3.5 为什么选用 varchar(2000) 而不是 clob / text

  • clob / text 在达梦中均按大对象存储,依然存在与空字符串比较的限制;
  • varchar(2000) 容量充足(cron 表达式 + 简单 JSON 配置远小于该值), 同时支持与空字符串直接比较;
  • varchar 在两个数据库(达梦 / MySQL)中行为一致,不存在跨库兼容问题。

四、对其他业务的影响评估

影响项 评估结论
AI-FLOW 业务功能 仅修复启动时 initCronTasksFromDB 的 SQL 执行,不改变功能逻辑
AI-FLOW 定时任务调度 修复后定时任务可正常从数据库加载并注册,新增能力(之前完全无法启动)
airag_flow 其他字段 字段类型未变动,不受影响
其他表 未涉及,不受影响
前端 AI-FLOW 流程编排 前端通过 trigger_cron 字段写入 JSON 字符串,不受影响
MySQL 环境 MySQL 中 text 字段与空字符串比较正常,不存在此问题,无需处理

五、验证步骤

  1. 执行 SQL:使用达梦客户端(disql / DM 管理工具 / DBeaver)连接到 ZJRS_JEECG_BOOT 模式 (application-dm8.yml 中配置的 schema),按 .docs/sql/AI-FLOW触发器兼容达梦数据库修复.sql 步骤执行;
  2. 确认字段类型变更
   SELECT DATA_TYPE, DATA_LENGTH, NULLABLE
   FROM USER_TAB_COLUMNS
   WHERE TABLE_NAME = 'AIRAG_FLOW'
     AND COLUMN_NAME = 'TRIGGER_CRON';
  1. 复现原报错 SQL
   SELECT id, trigger_cron FROM airag_flow
   WHERE (status = 'enable' AND (trigger_cron IS NOT NULL AND trigger_cron <> ''));

预期:正常返回(不抛 -6105)。

  1. 重启后端服务
   cd D:\我的文件\JeecgBoot-main\jeecg-boot
   mvn spring-boot:run -pl jeecg-module-system/jeecg-system-start `
       -Dspring-boot.run.jvmArguments="-Dfile.encoding=UTF-8"
  1. 观察启动日志:确认不再出现以下关键字的报错:
    • AI-FLOW 初始化定时触发器任务失败
    • dm.jdbc.driver.DMException: -6105
    • 数据类型不匹配
  2. (可选)功能验证:进入前端 AI-FLOW 流程编排页面,创建一个配置了 cronTrigger 的流程并保存,确认数据正常写入 airag_flow.trigger_cron 字段,后端能正确读取并调度执行。

六、回滚方案

如修复后出现问题,可执行以下 SQL 回滚(将 trigger_cron 还原为 TEXT 类型,注意 4 步流程会产生新 CLOB 列):

ALTER TABLE airag_flow ADD COLUMN trigger_cron_bak TEXT NULL;
UPDATE airag_flow SET trigger_cron_bak = CAST(trigger_cron AS TEXT);
ALTER TABLE airag_flow DROP COLUMN trigger_cron;
ALTER TABLE airag_flow RENAME COLUMN trigger_cron_bak TO trigger_cron;

⚠️ 回滚后请勿再使用 trigger_cron <> '' 这类 SQL,否则会再次触发 同样的 -6105 错误。

七、参考信息

  • JeecgBoot 版本:3.9.2
  • 数据库:达梦 DM8(compatibleMode=oracle
  • 出错模块:org.jeecg.modules.airag.flow(JeecgBoot 商业插件,无源码)
  • MyBatis-Plus 版本:3.5.12
  • 涉及 Flyway 历史脚本:V3.9.1_0__all_upgrade.sql(添加 trigger_cron 字段)
  • 修复实测环境:Windows 11 + JDK 17.0.4 + DmJdbcDriver18-8.1.3.140

八、追加修复:关闭 AI 视频配音工具检测日志

8.1 问题现象

启动日志中输出以下 WARN 提示,用户确认视频配音功能不需要使用:

2026-06-04 11:39:14.626 [main] INFO  o.j.m.a.v.service.impl.VideoGenerationServiceImpl:112 - === AI视频配音工具检测 ===
2026-06-04 11:39:14.627 [main] WARN  o.j.m.a.v.service.impl.VideoGenerationServiceImpl:116 -   ffmpeg   : 未安装,视频配音功能将不可用
2026-06-04 11:39:14.627 [main] WARN  o.j.m.a.v.service.impl.VideoGenerationServiceImpl:121 -   edge-tts : 未安装,视频配音功能将不可用
2026-06-04 11:39:14.627 [main] WARN  o.j.m.a.v.service.impl.VideoGenerationServiceImpl:126 -   视频配音功能: 已禁用(缺少依赖工具,调用配音接口将直接返回无声视频)

8.2 修改内容

修改文件:jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/video/service/impl/VideoGenerationServiceImpl.java

@PostConstruct init() 方法中的 ffmpeg/edge-tts 检测日志输出全部移除,仅保留工具路径查找逻辑(不影响后续功能判断),替换为注释 // 视频配音功能已关闭,不再输出检测日志

8.3 影响评估

  • 视频配音功能本身未删除,isToolsAvailable() 仍可正常判断工具是否可用;
  • 仅移除启动时的日志提示,不影响其他业务逻辑;
  • 若后续需要重新启用配音功能,安装 ffmpeg/edge-tts 后功能自动恢复。