我在 Firebird 上调用存储过程时遇到问题。我的过程有一个参数 (UID),并返回一个值 ID。
...
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// sp declaration
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
.withProcedureName("SP_NEWRECORD").declareParameters(
new SqlParameter("UID", Types.INTEGER),
new SqlOutParameter("NEWID", Types.INTEGER));
Map<String, Object> in = new HashMap<String, Object>();
in.put("UID", uid);
in.put("NEWID", 0);
try {
Map<String, Object> out = jdbcCall.execute(in); //here throws Exception
last_inserted = Integer.parseInt(String.valueOf(out.get("NEWID")));
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("createRecord result id=" + last_inserted);
}
// return id of inserted record
return last_inserted;
卡特琳娜出局
java.lang.NullPointerException
at org.firebirdsql.jdbc.AbstractResultSet.getRow(AbstractResultSet.java:1307)
at org.firebirdsql.jdbc.AbstractCallableStatement.assertHasData(AbstractCallableStatement.java:998)
at org.firebirdsql.jdbc.AbstractCallableStatement.getObject(AbstractCallableStatement.java:773)
at com.mchange.v2.c3p0.impl.NewProxyCallableStatement.getObject(NewProxyCallableStatement.java:675)
at org.springframework.jdbc.core.JdbcTemplate.extractOutputParameters(JdbcTemplate.java:1168)
SP的代码很简单,在表中创建新记录并返回插入记录的ID
ALTER PROCEDURE SP_NEWRECORD (UID integer)
RETURNS (NEWID integer)
AS
declare variable ID integer;
begin
ID=GEN_ID(gen_myrecords_id,1);
insert into myrecords (id,uid)
values (:id,:uid);
newid=ID;
end
最佳答案
最终的问题是,目前 Jaybird 没有明确区分 OUT
参数(Firebird 技术上没有)、可执行过程的(单行)返回值和(多个row) 可选存储过程的结果集。您遇到的问题(至少部分)与JDBC-229相关。 (以及对 Jaybird 3.0 计划的 CallableStatement
实现的总体回顾)。
这会导致支持单行的结果集被读取两次,一次作为 ResultSet
读取,一次通过 CallableStatement
上的 getter 读取,但是作为支持结果集已关闭,这会在检索 OUT
参数时导致 NullPointerException
。
有两种可能的解决方法:
在
JdbcTemplate
上禁用结果处理:JdbcTemplate jdbcTemplate = new JdbcTemplate(ds); jdbcTemplate.setSkipResultsProcessing(true);
不声明
OUT
参数,并处理out
映射中返回的结果集(其中包含一个List
结果集带有Map
):last_inserted = (int) ((List<Map>) out.get("#result-set-1")).get(0).get("NEWID");
请注意,从 Object
到 int
的转换假定使用 Java 7 或更高版本。
我已将此特定问题报告为 JDBC-350我将尝试在下一个 Jaybird 版本 (2.2.6) 中修复此问题。
关于sql - Firebird DB 上的 SimpleJdbcCall NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23238260/