我正在尝试调用Oracle存储过程,该存储过程从使用Hibernate和c3p0连接池的java应用程序返回隐式结果集。
如果在c3p0上启用了语句池,则每次从代码中调用存储过程都会抛出SQLException,并显示“ORA-01002 fetch out of sequence”消息。只有在启用了c3p0语句池时才会发生这种情况;否则一切正常。
相关的代码:
return session.doReturningWork(new ReturningWork<List<Foo>>()
{
@Override
public List<Foo> execute(Connection connection)
throws SQLException
{
C3P0ProxyConnection
castCon = (C3P0ProxyConnection) ((JdbcWrapper<Connection>) connection).getWrappedObject();
try(
CallableStatement stmnt =castCon.prepareCall("call proc_implicit(?)");
)
{
stmnt.setLong(1, 1L);
stmnt.executeQuery();
if (stmnt.getMoreResults())
{
List<Foo> retval = new ArrayList<>();
try (ResultSet rs1 = stmnt.getResultSet())
{
while (rs1.next())
{
retval.add(FooResultSetConverter.fromResulSet(rs1));
}
}
return retval;
}
}
return null;
};
});
在这种情况下,似乎c3p0池阻止了正确的资源释放,因此第二个executeQuery()
会抛出错误,从而正确释放资源,从而允许第三次执行,依此类推。
我想知道是否可以直接释放与Statement关联的ResultSet资源。我尝试了ResultSet.close()
,CallableStatement.close()
无济于事(毫不奇怪,连接池必须拦截并覆盖这些调用)。
当然,更改过程以使用SYS_REFCURSOR
输出参数而不是使用DBMS_SQL.RETURN_RESULT
返回结果,但我真的喜欢隐式结果集的想法。