You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jdbc:outbound-gateway插入数据库报错,请求技术支持

问题描述

使用Spring Integration的int-jdbc:outbound-gateway插入数据库数据时,通过:headers[id]或:headers.id获取Header值会报错,但硬编码固定值可正常插入。同时需要解决如何通过该组件插入Blob类型的payload数据。

配置代码

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xmlns:int-http="http://www.springframework.org/schema/integration/http"
    xmlns:task="http://www.springframework.org/schema/task"
    xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
                        http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa.xsd
                        http://www.springframework.org/schema/integration/http https://www.springframework.org/schema/integration/http/spring-integration-http.xsd
                        http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
                        http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                        http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
                        http://www.springframework.org/schema/tx https://www.springframework.org/schema/tx/spring-tx.xsd
                        http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms.xsd">

    <import
        resource="classpath:integration/spring-integration-database-context.xml" />

    <!-- Channels -->
    <int:gateway id="requestGatewayIntegration"
        service-interface="ca.bell.bmf.customer.gateway.CustomerProfileGateway"
        default-request-channel="objectToJsonChannel"
        error-channel="errorChannel11" />

    <int:channel id="objectToJsonChannel">
        <int:interceptors>
            <bean class="ca.bell.bmf.customer.service.MyChannelInterceptor" />
        </int:interceptors>

    </int:channel>
    
    
    <int-jdbc:outbound-gateway
    update="Insert into INT_CHANNEL_MESSAGE (MESSAGE_ID, GROUP_KEY,CREATED_DATE,MESSAGE_PRIORITY,MESSAGE_SEQUENCE,REGION) 
    values(:headers[id],:headers[id],'1211','2','3','Test')"
    request-channel="objectToJsonChannelTMF639" reply-channel="responseobjectToJsonChannelTMF639" data-source="dataSource" />   

</beans>

正常工作的硬编码配置

<int-jdbc:outbound-gateway update="Insert into INT_CHANNEL_MESSAGE (MESSAGE_ID, GROUP_KEY,CREATED_DATE,MESSAGE_PRIORITY,MESSAGE_SEQUENCE,REGION)  values('242452','','1211','2','3','Test')" request-channel="objectToJsonChannelTMF639" reply-channel="responseobjectToJsonChannelTMF639" data-source="dataSource" />

报错信息

from source: ''int-jdbc:outbound-gateway''' while handling 'GenericMessage [payload=CPMPayload ': error occurred in message handler [bean 'org.springframework.integration.jdbc.JdbcOutboundGateway#0'; defined in: 'URL [file:/C:/Users/19.3/Git/profile/process/target/classes/integration/Profile-context.xml]'; from source: ''int-jdbc:outbound-gateway'']; nested exception is org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [Insert into INT_CHANNEL_MESSAGE (MESSAGE_ID, GROUP_KEY,CREATED_DATE,MESSAGE_PRIORITY,MESSAGE_SEQUENCE,REGION)      values(?,?,'1211','2','3','Test')]; SQL state [99999]; error code [17004]; Invalid column type; nested exception is java.sql.SQLException: Invalid column type. Failing over to the next subscriber.
解决方案

一、解决Header取值与类型不匹配问题

报错Invalid column type的核心原因是Header中id的值类型与数据库表INT_CHANNEL_MESSAGE的MESSAGE_ID、GROUP_KEY列类型不兼容,Spring无法自动完成类型转换。可以尝试以下方法:

1. 显式指定参数类型

在配置中添加parameter-types属性,按照SQL占位符的顺序,逐个指定参数对应的JDBC类型,确保和数据库列类型一致:

<int-jdbc:outbound-gateway
    update="Insert into INT_CHANNEL_MESSAGE (MESSAGE_ID, GROUP_KEY,CREATED_DATE,MESSAGE_PRIORITY,MESSAGE_SEQUENCE,REGION) 
    values(:headers[id],:headers[id],'1211','2','3','Test')"
    request-channel="objectToJsonChannelTMF639" 
    reply-channel="responseobjectToJsonChannelTMF639" 
    data-source="dataSource"
    parameter-types="VARCHAR,VARCHAR,DATE,INTEGER,INTEGER,VARCHAR"/>

注意:parameter-types的顺序必须和SQL中占位符的顺序完全对应,前两个对应Header的id,后续依次匹配其他列的类型。

2. 转换Header值类型

如果Header中的id是UUID、数字等非字符串类型,直接插入会导致类型不匹配。可以在发送消息前提前转换类型,或者在SpEL表达式中直接转换:

update="Insert into INT_CHANNEL_MESSAGE (...) values(:headers[id].toString(),:headers[id].toString(),'1211','2','3','Test')"

3. 验证Header存在性

先确认消息Header中确实存在id这个键,且值不为空。可以添加日志拦截器打印Header内容,排查键名是否拼写错误,:headers.id或:headers['id']的写法都是合法的,只要键存在即可。

二、插入Blob类型的Payload数据

要插入Blob类型的数据,需要在SQL中引用:payload,同时指定参数类型为BLOB,并且确保Payload本身是字节数组或可转换为字节流的对象。

配置示例

假设INT_CHANNEL_MESSAGE表有一个MESSAGE_CONTENT列是Blob类型,配置修改如下:

<int-jdbc:outbound-gateway
    update="Insert into INT_CHANNEL_MESSAGE (MESSAGE_ID, GROUP_KEY,CREATED_DATE,MESSAGE_PRIORITY,MESSAGE_SEQUENCE,REGION,MESSAGE_CONTENT) 
    values(:headers[id],:headers[id],'1211','2','3','Test',:payload)"
    request-channel="objectToJsonChannelTMF639" 
    reply-channel="responseobjectToJsonChannelTMF639" 
    data-source="dataSource"
    parameter-types="VARCHAR,VARCHAR,DATE,INTEGER,INTEGER,VARCHAR,BLOB"/>

额外处理:Payload为字符串的情况

如果Payload是JSON字符串等文本类型,需要先转换为字节数组,可以添加转换器完成这个步骤:

<!-- 将Payload转换为字节数组 -->
<int:transformer input-channel="objectToJsonChannelTMF639" output-channel="payloadToBytesChannel">
    <int:transformer expression="payload.toString().getBytes()"/>
</int:transformer>

<int:channel id="payloadToBytesChannel"/>

<!-- 修改outbound-gateway的请求通道为转换后的通道 -->
<int-jdbc:outbound-gateway
    update="Insert into INT_CHANNEL_MESSAGE (...) values(...,:payload)"
    request-channel="payloadToBytesChannel" 
    data-source="dataSource"
    parameter-types="VARCHAR,VARCHAR,DATE,INTEGER,INTEGER,VARCHAR,BLOB"/>

如果Payload是自定义对象,需要自定义转换器将对象序列化为字节数组(比如用Jackson将对象转为JSON字节流)。

内容的提问来源于stack exchange,提问作者Rajesh Moorthi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:29:52