Apache camel 获取 Oracle 数据库生成的 ID
Apache camel getting Oracle database generated ID
我正在使用 camel jdbc 组件将记录插入 Oracle table。插入使用序列填充主键 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
中,我将消息 body 设置为我的插入语句,还设置了一些两个 header 值来指示 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。实际上,消息的 header 中没有插入记录,也没有 ID 存在。没有最终处理器一切正常。
显然我在这里做错了什么,但我不知道是什么。我知道我可以使用消息 en-richer 在插入之前获取 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);
}
这是我的研究停止的地方,因为在各种 3 方代码中挖掘太多并不是一件容易的事。我怀疑以下两个选项之一是原因:
- 我做的还是不对
- 当 header 包含命名参数和 检索生成的密钥 设置时,无法按预期工作的骆驼错误
请告知任何修复或解决方法。
再次感谢
我也运行加入这个。我的解决方法:
使用骆驼-sql 而不是骆驼-jdbc。添加 parametersCount
选项到端点 URL(除了 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 驱动程序)。
我正在使用 camel jdbc 组件将记录插入 Oracle table。插入使用序列填充主键 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
中,我将消息 body 设置为我的插入语句,还设置了一些两个 header 值来指示 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。实际上,消息的 header 中没有插入记录,也没有 ID 存在。没有最终处理器一切正常。
显然我在这里做错了什么,但我不知道是什么。我知道我可以使用消息 en-richer 在插入之前获取 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);
}
这是我的研究停止的地方,因为在各种 3 方代码中挖掘太多并不是一件容易的事。我怀疑以下两个选项之一是原因:
- 我做的还是不对
- 当 header 包含命名参数和 检索生成的密钥 设置时,无法按预期工作的骆驼错误
请告知任何修复或解决方法。
再次感谢
我也运行加入这个。我的解决方法:
使用骆驼-sql 而不是骆驼-jdbc。添加 parametersCount
选项到端点 URL(除了 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 驱动程序)。