首页 > 解决方案 > 查询 Oracle 的错误时,避免 Stream 的任何解决方法已经关闭?

问题描述

我正在使用 ojdbc8 版本 21.1.0.0 作为我的 JDBC。我遇到的问题是每次调用之前我的连接流都会关闭,close()当我执行我的查询时,由于未知原因从 resultSet 请求了很长时间,并且我的 SQL 在 SQL 开发人员上运行良好。所以我用谷歌搜索并看到甲骨文报告了这个错误。

https://support.oracle.com/knowledge/Middleware/832903_1.html

似乎这是他们的 JDBC 的错误?有谁知道哪个版本的 ODBC8 没有这个 bug?或其他解决方法以避免此错误?

==== 更新 ====

@斯蒂芬C

好吧,如果你这么说。但我认为这无论如何都无济于事,因为代码本身太简单了,不会有这样的错误。

class Channel {
    private static DataSource ds = null;
    private static final String GET_ONE = "SELECT * FROM Channel WHERE Id=?";
    
    public Channel() {
        if(ds == null) {
            try {
                Context ctx = new InitialContext();
                ds = (DataSource) ctx.lookup("jdbc/oracle");
            } catch (NamingException e) {
                e.printStackTrace();
            }
        }
    }

    public HashMap<String, Object> getOne(String id) throws SQLException{
        HashMap<String, Object> result = null;
        ResultSet rs = null;
        
        try(Connection conn = ds.getConnection();
            PreparedStatement pstmt = con.prepareStatement(GET_ONE);){
            
            pstmt.setString(1, id);
            
            rs = pstmt.executeQuery();
            
            if(rs.next()){
                result = new HashMap<String, Object>();
                result.put("Time_Limit", rs.getLong("Time_Limit"));// recommended by @tgdavies
                result.put("Id", rs.getString("Id"));
                result.put("Name", rs.getString("Name"));
            }
        
        } catch(SQLException e){
            throw e;
        } finally {
            if(rs != null){
                try{
                    rs.close();
                } catch(SQLException e){}
            }
        }
        
        return result;
    }
}

标签: javaoraclejdbc

解决方案


我想我知道问题是什么。

(警告:您没有包含堆栈跟踪,因此我无法确认这一点。此外,您发布的链接未打开,因此我们无法看到您正在谈论的错误报告的详细信息。)

    try(Connection conn = ds.getConnection();
        PreparedStatement pstmt = con.prepareStatement(GET_ONE);){
        
        pstmt.setString(1, id);
        
        rs = pstmt.executeQuery();
        
        if(rs.next()){
            result = new HashMap<String, Object>();
            result.put("Time_Limit", rs.getLong("Time_Limit"));// recommended by @tgdavies
            result.put("Id", rs.getString("Id"));
            result.put("Name", rs.getString("Name"));
        }
    
    } catch(SQLException e){
        throw e;
    } finally {
        if(rs != null){
            try{
                rs.close();
            } catch(SQLException e){}
        }
    }

问题是finally在资源自动关闭之后执行。因此,您的代码将在关闭rs.close()后调用。PreparedStatement但关闭语句会关闭从该语句创建的任何结果集。

参考:

可能的解决方案:

  1. 也将其ResultSet视为资源;例如,使用资源的嵌套尝试
  2. 摆脱finally...

推荐阅读