canal-adapter报错空指针:java.lang.NullPointerException at com.alibaba.otter.canal.client.adapter.es7x.etl.ESEtlService.lambda$executeSqlImport$1(ESEtlService.java:73)
问题
在新增一个 mysql 同步到 es 的作业时. 发现数据消费包括消费的上游一切正常, 但是es中数据是空的.
检查canal-adapter 日志发现 有报错空指针如下:
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
at com.alibaba.otter.canal.client.adapter.es7x.etl.ESEtlService.lambda$executeSqlImport$1(ESEtlService.java:191) [client-adapter.es7x-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
at com.alibaba.otter.canal.client.adapter.support.Util.sqlRS(Util.java:60) ~[client-adapter.common-1.1.5-SNAPSHOT.jar:na]
... 59 common frames omitted
Caused by: java.lang.NullPointerException: null
at com.alibaba.otter.canal.client.adapter.es7x.etl.ESEtlService.lambda$executeSqlImport$1(ESEtlService.java:73) [client-adapter.es7x-1.1.5-SNAPSHOT-jar-with-dependencies.jar:na]
... 60 common frames omitted
2023-02-01 17:11:08.963 [http-nio-8081-exec-2] INFO c.a.otter.canal.client.adapter.es7x.etl.ESEtlService - 数据全量导入完成, 一共导入 0 条数据, 耗时: 44
2023-02-01 17:11:17.086 [http-nio-8081-exec-4] INFO c.a.otter.canal.client.adapter.es7x.etl.ESEtlService - start etl to import data to index: ydky_dot_dot_customer_v1
问题查错思路
首先是顺腾摸瓜, 找到 源码中 ESEtlService.java:73 这个部分
该行代码为 : for (FieldItem fieldItem : mapping.getSchemaItem().getSelectFields().values()) ( 源码截图在下面)
因为不太确定代码含义,所以继续查看这个SchemaItem 是何许人也? (源码图在下面)
很贴心. 直接中文注释. 那可以直接下结论了. 就是 根据配置文件中的映射字段 在实际mysql的表里面没有找到.
解决方案
方便新接触canal人员上手.我尽量写的详细一点.
第一步找到映射配置文件.
路径
然后找到你对应出错的配置 ,打开.找到那个sql 映射
我的如下:
就是它了.
第二步 把这个sql copy出来
sql 运行一下. 可以正常查询. 但是可以明显看出这个sql 字段的大小写. 有的开头大写 有的全是小写. 问题应该就是出在这里了.
第三步 修改错误sql
mysql 的sql 在运行时. 会 统一转换为大写.所以不区分大小写. 但是在canal-adapter 源码中. 进行字段匹配的时候.字段是以linkedHashMap<String,String>形式存放, 本质是字符串等于,是区分大小写的.
修改好sql 重新配置上去.果不其然, 问题解决!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端