Kafka Connect Solace源与JDBC Sink配Avro时报Value schema must be of type Struct错误
问题根因定位
报错org.apache.kafka.connect.errors.ConnectException: Value schema must be of type Struct的核心逻辑链完全清晰,和当前配置的两处缺陷直接相关:
- JDBC Sink Connector存在硬性校验规则:所有要同步到关系型数据库的Kafka消息Value,必须是带字段定义的Struct结构类型,因为需要将Struct的每个字段映射为数据库的对应列。它完全不支持字符串、整数这类基础数据类型的消息值——没有字段结构就无法完成列映射。
- 当前的Solace Source Connector未输出Struct类型的消息:
- 配置里的
key.converter.schemas.enable=false、value.converter.schemas.enable=false是旧版JSON/字符串Converter的专属参数,对AvroConverter完全无效,不会起到任何配置作用。 - Solace Source Connector默认的消息转换逻辑,会把Solace收到的原始消息payload作为独立基础类型(通常是字符串/字节数组)序列化后发到Kafka,就算用AvroConverter反序列化,得到的也只是基础类型值,根本不包含结构化字段,自然通不过JDBC Sink的类型校验。
- 配置里的
- 能在Kafka主题里看到消息是正常现象:控制台消费端只做Avro字节的可读化展示,不会校验消息对应的Connect Schema结构,这种展示效果和是否符合JDBC Sink的Struct要求没有关联。
分步修复方案
- 修正Solace Source Connector的转换配置
- 先删除所有冗余的
*.converter.schemas.enable=false配置,这类参数对AvroConverter无意义,留着只会造成配置认知偏差。 - 开启Solace Source的Struct消息转换器,新增配置:
solace.source.message.converter=com.solace.connector.kafka.connect.source.converter.SolaceMessageToStructConverter。这个转换器会自动把Solace消息的核心元数据(目的地、关联ID、时间戳)和消息payload封装为带完整字段定义的Struct结构,序列化到Kafka的Avro数据会变成带字段的Record类型,而非裸基础类型。 - 如果需要把Solace消息内的业务字段直接拆为Struct顶级字段,而不是统一存在payload子字段内,需要在Source侧配置对应字段的Schema映射规则,逐一定义业务字段的名称、类型,保证最终生成的Struct结构满足数据库列映射要求。
- 先删除所有冗余的
- 验证Kafka主题的消息Schema
确认testtopic对应的Avro Value Schema为Record类型(包含fields数组定义),排除基础类型(仅定义type: string/type: int这类无字段的Schema)的旧消息残留。 - 修正JDBC Sink Connector的匹配配置
- 同样删除冗余的
*.converter.schemas.enable=false配置。 - 调整Oracle侧的
TEST_TABLE1表结构,让表列和Source生成的Struct字段一一对应。比如Struct包含payload、solace_destination字段,表内就要创建同名字段的VARCHAR2类型列来承接数据。 - 清理主题内残留的、非Struct类型的历史消息:这类旧消息就算配置修正后,被Sink拉取时依然会触发相同的类型校验错误,需要调整消费者偏移量跳过这段历史数据。
- 同样删除冗余的
常见踩坑提示
AvroConverter本身不负责生成Struct结构,它仅做Kafka存储的Avro字节和Connect内部数据类型的双向映射:如果Kafka上存的是基础类型的Avro schema,转换结果就是基础类型数据;只有存的是Record结构的Avro schema,转换结果才是Struct类型。JDBC Sink的校验逻辑完全独立于Converter选型,只校验最终拿到的Value Schema类型,这也是报错没有指向Converter配置问题的核心原因。
内容的提问来源于stack exchange,提问作者Prateek Gupta
相关产品推荐
相关产品推荐

