我正在使用camel jdbc组件将记录插入到Oracle表中。插入使用序列来填充主键ID列。
INSERT INTO my_table (id, data) VALUES (my_seq.nextval, 'some data')
该路线的相关部分如下所示:
from("some end point here")
.process(preInsertProcessor)
.to("jdbc:myDataSource")
.process(new Processor() {
public void process(Exchange exchange) throws Exception {
LOGGER.info("Extracting database generated id");
// This list is null
List<Integer> ids = exchange.getIn().getHeader(
JdbcConstants.JDBC_GENERATED_KEYS_DATA, List.class);
});
在preInsertProcessir
内部,我将消息体设置为我的insert语句,并设置了两个标头值来指示camel我想要生成的ID:
message.setBody("INSERT INTO my_table (id, data) VALUES (my_seq.nextval, ?:data)");
message.setHeader("data", "some data");
message.setHeader(JDBC_RETRIEVE_GENERATED_KEYS, true);
message.setHeader(JDBC_GENERATED_COLUMNS, new String[]{"ID"});
如果我查看我能看到的日志,请结束:
[DEBUG] org.apache.camel.component.bean.MethodInfo - Setting bean invocation result on the OUT message: [Message: INSERT INTO my_table(id, data)VALUES (my_seq.nextval, :?data]
[DEBUG] org.apache.camel.spring.spi.TransactionErrorHandler - Transaction begin (0x1de4bee0) redelivered(false) for (MessageId: ID-MELW1TYGC2S-62650-1438583607644-0-8 on ExchangeId: ID-MELW1TYGC2S-62650-1438583607644-0-9))
[INFO ] au.com.nab.cls.router.non.repudiation.GeneratedIdExtractor - Extracting database generated id
[DEBUG] org.apache.camel.processor.MulticastProcessor - Done sequential processing 1 exchanges
[DEBUG] org.apache.camel.spring.spi.TransactionErrorHandler - Transaction commit (0x1de4bee0) redelivered(false) for (MessageId: ID:414d5120445041594855423120202020027844552045b302 on ExchangeId: ID-MELW1TYGC2S-62650-1438583607644-0-7))
如果我从日志的外观上看得很清楚,就会执行插入操作,而我的最终处理器应该能够获得生成的ID。实际上,发生的事情是没有插入记录,并且消息的标题中不存在ID。没有最终处理器,一切正常。
显然我在这里做错了但我无法弄清楚是什么。我知道我可以使用一个更丰富的消息来获取插入之前的ID,但我宁愿避免额外的数据库之旅。
提前感谢您的意见。
更新
我在org.apache.camel.component.jdbc.JdbcProducer
中设置了一个断点,并找出了没有执行INSERT的原因,因此没有得到ID。
// JdbcProducer code; creating a prepared statement part
if (shouldRetrieveGeneratedKeys) {
...
} else if (expectedGeneratedColumns instanceof String[]) {
// Execution gets herestatement
ps = conn.prepareStatement(preparedQuery, (String[]) expectedGeneratedColumns);
...
}
// Expected count returned here is 2
int expectedCount = ps.getParameterMetaData().getParameterCount();
if (expectedCount > 0) {
...
// And here I get the crash:
// java.sql.SQLException: Number of parameters mismatch. Expected: 2, was:1
getEndpoint().getPrepareStatementStrategy().populateStatement(ps, it, expectedCount);
}
这是我的研究停止的地方,因为在各种三方代码中挖掘太多并不容易。我怀疑以下两个选项之一是原因:
请告知任何修复或解决方法。
再次感谢
答案 0 :(得分:1)
我也碰到了这个。我的解决方法:
使用camel-sql而不是camel-jdbc。将parametersCount
选项添加到端点网址(除setHeader(SqlConstants.SQL_RETRIEVE_GENERATED_KEYS, constant(true))
和setHeader(SqlConstants.SQL_GENERATED_COLUMNS, constant(new String[] {"ID_COLUMN_NAME"})
之外)。
更新:与11.2.0.4
jdbc驱动程序一起使用(不适用于12.2.0.1
jdbc驱动程序。)