我在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;
Catalina out
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
答案 0 :(得分:1)
最终的问题是,目前Jaybird没有明确区分OUT
参数(Firebird技术上没有),可执行程序的(单行)返回值和(多行)结果一组可选择的存储过程。您遇到的问题(至少部分)与JDBC-229相关(以及对Jaybird 3.0计划的CallableStatement
实施的一般性审核)。
这会导致支持单行的结果集被读取两次,一次作为ResultSet
,一次通过CallableStatement
上的getter,但是当支持结果集已关闭时,这会在检索到NullPointerException
参数时导致OUT
。
有两种可能的解决方法:
禁用JdbcTemplate
上的结果处理:
JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
jdbcTemplate.setSkipResultsProcessing(true);
不要声明OUT
参数,并处理out
地图中返回的结果集(其中包含带有List
的{{1}}结果集):
Map
请注意,从last_inserted = (int) ((List<Map>) out.get("#result-set-1")).get(0).get("NEWID");
到Object
的强制转换假设为Java 7或更高版本。
我已将此特定问题报告为JDBC-350,我将尝试在下一个Jaybird版本(2.2.6)中修复此问题。