Apache驼峰获取Oracle数据库生成的ID

时间:2015-08-03 07:28:13

标签: apache-camel

我正在使用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);
 }

这是我的研究停止的地方,因为在各种三方代码中挖掘太多并不容易。我怀疑以下两个选项之一是原因:

  1. 我仍然没有采用正确的方式
  2. 当标头包含命名参数和检索生成的密钥设置
  3. 时,骆驼错误无法正常工作

    请告知任何修复或解决方法。

    再次感谢

1 个答案:

答案 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驱动程序。)