sql - Firebird DB 上的 SimpleJdbcCall NullPointerException

标签 sql spring stored-procedures jdbc firebird

我在 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

有两种可能的解决方法:

  1. JdbcTemplate 上禁用结果处理:

    JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
    jdbcTemplate.setSkipResultsProcessing(true);
    
  2. 不声明OUT参数,并处理out映射中返回的结果集(其中包含一个List 结果集带有 Map):

    last_inserted = (int) ((List<Map>) out.get("#result-set-1")).get(0).get("NEWID");
    

请注意,从 Objectint 的转换假定使用 Java 7 或更高版本。

我已将此特定问题报告为 JDBC-350我将尝试在下一个 Jaybird 版本 (2.2.6) 中修复此问题。

关于sql - Firebird DB 上的 SimpleJdbcCall NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23238260/

相关文章:

java - Hibernate:更新表查询不起作用

java - Spring 单元测试: Autowire the Implementation of an Interface directly?

spring - 如何使用 Camel 2.9 定义自定义 CamelBeanPostProcessor

.net - 事务应该在存储过程外部还是内部指定?

postgresql - 存储过程帮助获取 ID 并从另一个表中获取结果

sql - OLE DB 提供程序 "ADSDSOObject"尚未在 Azure SQL 托管实例中注册

mysql - 如何检查所选日期范围是否在另一个日期范围之间

java - 组织.apache.catalina.LifecycleException : Failed to start component

c# - 调用 Oracle 存储过程。获取 'No Data Found' 异常

用于搜索小写字符串的 SQL 查询