Java 存储的proc出站网关中的参数数量不定
我正在构建一个应用程序(使用spring集成),它应该从任何入站网关接收请求对象,并调用MS SQL存储过程。 请求对象包含Java 存储的proc出站网关中的参数数量不定,java,spring,spring-integration,spring-jdbc,Java,Spring,Spring Integration,Spring Jdbc,我正在构建一个应用程序(使用spring集成),它应该从任何入站网关接收请求对象,并调用MS SQL存储过程。 请求对象包含StringattributeprocedureName和Listattributeparameters。问题是我找不到解决方案,当我在编译时不知道参数列表的长度时,如何传递参数列表。 出站网关的配置: <int-jdbc:stored-proc-outbound-gateway id="outbound-gateway-procedure" requ
String
attributeprocedureName
和List
attributeparameters
。问题是我找不到解决方案,当我在编译时不知道参数列表的长度时,如何传递参数列表。
出站网关的配置:
<int-jdbc:stored-proc-outbound-gateway
id="outbound-gateway-procedure" request-channel="requestChannel"
data-source="dataSource" stored-procedure-name-expression="payload.procedureName"
sql-parameter-source-factory="someParameterSourceFactory" >
</int-jdbc:stored-proc-outbound-gateway>
但我不知道编译时的参数数量和名称。有什么建议吗
UPD:
存储过程如下所示:
<bean id="someParameterSourceFactory" class="org.springframework.integration.jdbc.ExpressionEvaluatingSqlParameterSourceFactory">
<property name="parameterExpressions">
<map>
<entry key="first" value-type="java.lang.String" value="payload.parameters.get(1).second"/>
<entry key="second" value-type="java.lang.String" value="payload.parameters.get(2).second"/>
</map>
</property>
</bean>
create procedure [dbo].[pnzLimitUtilization_Show]
(
@BookDate datetime
, @LegalGroupList varchar(4000)
, @Currency char(3)
, @FilterForAny nvarchar(255) = ''
, @RiskZone char(1) = 'A'
, @WithZerroExposure char(1) = '0'
, @Transliteration bit = 0
, @IsNewMethodology bit = 0
, @UtilizationType char(1) = 'A'
, @PartyGroupList varchar(255) = NULL
, @HostName varchar(255) = NULL
, @ShowCloseExpiration bit = 0
, @CloseExpirationDays int = 90
, @WhatIfDealFilter char(1) = 'R'
, @HideLESublimits bit = 0
)
as begin ....
新配置:
<int-jdbc:stored-proc-outbound-gateway
id="outbound-gateway-procedure" request-channel="requestChannel"
data-source="dataSource" stored-procedure-name-expression="payload.name.toString()"
ignore-column-meta-data="true"
sql-parameter-source-factory="listParameterSourceFactory"
reply-channel="replyChannel">
</int-jdbc:stored-proc-outbound-gateway>
<bean id="listParameterSourceFactory" class="my.pack.integration.ListSqlParameterSourceFactory" />
我通过ListSqlParameterSourceFactory进行了调试,它按预期工作,SqlParameterSource是
[0] = {java.util.HashMap$Entry@4243}"@Currency" -> "R"
[1] = {java.util.HashMap$Entry@4246}"@LegalGroupList" -> "( ALL )"
[2] = {java.util.HashMap$Entry@4249}"@FilterForAny" -> ""
[3] = {java.util.HashMap$Entry@4252}"@ShowCloseExpiration" -> "0"
[4] = {java.util.HashMap$Entry@4255}"@IsNewMethodology" -> "0"
[5] = {java.util.HashMap$Entry@4258}"@CloseExpirationDays" -> "0"
[6] = {java.util.HashMap$Entry@4261}"@WhatIfDealFilter" -> "R"
[7] = {java.util.HashMap$Entry@4264}"@UtilizationType" -> "A"
[8] = {java.util.HashMap$Entry@4267}"@BookDate" -> "20141202 00:00:00.000"
[9] = {java.util.HashMap$Entry@4270}"@Transliteration" -> "0"
[10] = {java.util.HashMap$Entry@4273}"@PartyGroupList" -> "( ALL )"
[11] = {java.util.HashMap$Entry@4276}"@RiskZone" -> "L"
[12] = {java.util.HashMap$Entry@4279}"@HideLESublimits" -> "0"
有什么我错过的吗
UPD2:
Spring jdbc日志:
05 dec 2014 14:15:28 DEBUG SimpleJdbcCall - Compiled stored procedure. Call string is [{call dbo.pnzLimitUtilization_Show()}]
05 dec 2014 14:15:28 DEBUG SimpleJdbcCall - SqlCall for procedure [dbo.pnzLimitUtilization_Show] compiled
05 dec 2014 14:15:28 DEBUG CallMetaDataContext - Matching [@FilterForAny, @BookDate, @Currency, @UtilizationType, @HideLESublimits, @ShowCloseExpiration, @Transliteration, @IsNewMethodology, @RiskZone, @WhatIfDealFilter, @CloseExpirationDays, @PartyGroupList, @LegalGroupList] with []
05 dec 2014 14:15:28 DEBUG CallMetaDataContext - Found match for []
05 dec 2014 14:15:28 DEBUG SimpleJdbcCall - The following parameters are used for call {call dbo.pnzLimitUtilization_Show()} with: {}
05 dec 2014 14:15:28 DEBUG JdbcTemplate - Calling stored procedure [{call dbo.pnzLimitUtilization_Show()}]
看起来它没有传递任何参数。。
调试CallMetaDataContext我发现this.callParameters
为空。它是否与忽略列元数据=“true”
连接?但是如果我将其切换到false
我会看到另一个错误:
05 dec 2014 14:41:33 DEBUG CallMetaDataProviderFactory - Using org.springframework.jdbc.core.metadata.SqlServerCallMetaDataProvider
05 dec 2014 14:41:33 DEBUG CallMetaDataProvider - Retrieving metadata for null/null/dbo.pnzLimitUtilization_Show
05 dec 2014 14:41:36 DEBUG DataSourceUtils - Returning JDBC Connection to DataSource
org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.jdbc.StoredProcOutboundGateway#0]; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Unable to determine the correct call signature for dbo.pnzLimitUtilization_Show - package name should be specified separately using '.withCatalogName("dbo")'
UPD3:
好的,我从过程名中删除了
dbo.
,从参数名中删除了@
,现在它正确地加载了列元数据和绑定变量。这并不意味着我的应用程序可以工作,但至少我可以更进一步。阿尔特姆的建议帮助解决了主要问题 首先,你的程序看起来怎么样?至少是规格
为什么您确定任何参数列表对于您的过程调用都是合法的
从另一方面来说,您可以正确地进行SqlParameterSourceFactory
定制,但它确实应该完全定制实现。类似这样,因为您说您的有效负载
具有参数
属性:
public class PairSqlParameterSourceFactory implements SqlParameterSourceFactory {
public SqlParameterSource createParameterSource(Object input) {
Message<Request> message = (Message<Request>) input;
List<Pair<String, Object>> pairs = message.getPayload().getParameters();
MapSqlParameterSource source = new MapSqlParameterSource();
for (Pair<String, Object> pair : pairs) {
source.addValue(pair.getName(), pair.getValue());
}
return source;
}
}
公共类PairSqlParameterSourceFactory实现SqlParameterSourceFactory{
公共SqlParameterSource createParameterSource(对象输入){
消息消息=(消息)输入;
列表对=message.getPayload().getParameters();
MapSqlParameterSource=新的MapSqlParameterSource();
对于(对:对){
addValue(pair.getName(),pair.getValue());
}
返回源;
}
}
尝试了此操作,但仍然无法正常工作。你能看看最新的帖子吗?我明白了。你真的错过了参数的顺序@BookDate
是过程规范的第一个。但是在您的SqlParameterSource
中,它位于[8]
位置.Artem,但是如果我们深入MapSqlParameterSource
中,我们会看到它将参数保存在通常的HashMap
中,而不是有序的。来自javadocs:该类用于将参数值的简单映射传递给NamedParameterJdbcTemplate类的方法。因此,我希望Spring将按名称绑定参数。实际上,我按正确的顺序传递参数,HashMap做所有的消息注意,我们这里有
,因此没有任何命名参数jdbctemplate
,只有SimpleJdbcCall#execute()
。尝试为org.springframework.jdbc
类别打开DEBUG,以跟踪过程准备和提供的参数的状态。
05 dec 2014 14:41:33 DEBUG CallMetaDataProviderFactory - Using org.springframework.jdbc.core.metadata.SqlServerCallMetaDataProvider
05 dec 2014 14:41:33 DEBUG CallMetaDataProvider - Retrieving metadata for null/null/dbo.pnzLimitUtilization_Show
05 dec 2014 14:41:36 DEBUG DataSourceUtils - Returning JDBC Connection to DataSource
org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.jdbc.StoredProcOutboundGateway#0]; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Unable to determine the correct call signature for dbo.pnzLimitUtilization_Show - package name should be specified separately using '.withCatalogName("dbo")'
public class PairSqlParameterSourceFactory implements SqlParameterSourceFactory {
public SqlParameterSource createParameterSource(Object input) {
Message<Request> message = (Message<Request>) input;
List<Pair<String, Object>> pairs = message.getPayload().getParameters();
MapSqlParameterSource source = new MapSqlParameterSource();
for (Pair<String, Object> pair : pairs) {
source.addValue(pair.getName(), pair.getValue());
}
return source;
}
}