PSQLException:此ResultSet已关闭

时间:2013-06-28 15:56:00

标签: java postgresql exception resultset

我生命中第一次出现这个奇怪的错误,我不知道这意味着什么。我有一个类从postgresql数据库的表中检索信息,做一些操作并返回带有解析元素的arraylist:

ResultSet rs = ProduttoreDCS.getProduttori();
        System.out.println("Recuperato result set produttori");
        ArrayList<String[]> res = new ArrayList<String[]>();


        while (rs.next()) {
            String[] current = new String[6];

            current[0] = Integer.toString(rs.getInt("partita_iva"));
            current[1] = rs.getString("nome");
            current[2] = rs.getString("cognome");
            current[3] = rs.getString("via_sede");
            current[4] = rs.getString("citta_sede");
            current[5] = rs.getString("provincia_sede");

            res.add(current);
            current = null;
        }

        return res;

错误在“while”行上。

public static ResultSet getProduttori() throws ClassNotFoundException, SQLException {
    /*
     * retrieve all record from produttori table
     */
    Connection conn = null;
    ResultSet res = null;
    Statement stmt = null;
    String query = "SELECT * FROM produttore";

    conn = ConnectionManager.getConnection();
    System.out.println("Connection obtained by ProduttoreDCS class");
    stmt = conn.createStatement();
    res = stmt.executeQuery(query);

    stmt.close();
    conn.close();


    return res;   
}

5 个答案:

答案 0 :(得分:5)

当您在getProduttori方法中关闭连接对象时,结果集将自动关闭。当你尝试重新使用它时,它将为null。

ResultSet rs = ProduttoreDCS.getProduttori();
             = null, as you have closed the connection in getProduttori
               method, which will automatically close the resultset 
               thus, it returns null.

来自 Connection#close

  

释放此Connection对象的数据库和JDBC资源   立即而不是等待它们自动释放。

关闭Statement时

也适用。对于你的代码来说,不要关闭Statement和Connection,直到你得到行。

@Baadshah已经向您展示了标准方式。如果你使用的是java 7+,你可以使用try-with-resource块,这会让你的生活变得更简单。

 try(Connection conn = gettheconn){
     get the statement here
     get the result set 
      perform your ops
 }
 catch(SQLException ex){
   ex.printstacktrace(); 
  }

如果您观察到,没有finally块,一旦您自动退出try块,您的连接对象将被关闭。您不必明确调用Connection#close()

答案 1 :(得分:3)

As per Docs

  

当生成它的Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,ResultSet对象会自动关闭。

你关闭了连接然后你正在迭代,它是null。请读取数据,然后关闭连接。

这里的一个好习惯是

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
    conn = 
    stmt = conn.prepareStatement("sql");
    rs = stmt.executeQuery();
   //DO SOME THING HERE
} catch {
    // Error Handling
} finally {
    try { if (rs != null) rs.close(); } catch (Exception e) {};
    try { if (stmt != null) stmt.close(); } catch (Exception e) {};
    try { if (conn != null) conn.close(); } catch (Exception e) {};
}

答案 2 :(得分:3)

这是问题所在:

stmt.close();
conn.close();

您正在关闭与数据库的连接。在您阅读数据之前,您无法做到这一点 - 否则ResultSet将如何阅读它?也许它会在开始时读取一些数据,但它并不意味着是一个断开连接的对象。

特别是来自ResultSet.close的文件:

  

注意:当Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,Statement对象会自动关闭它生成它的Statement对象。

答案 3 :(得分:3)

我通过运行以下错误的组合遇到了相同的问题

Postgres版本; 休眠方言; postgres jdbc驱动程序;

将所有更新到最新版本为我解决了这个问题。

P.S。我知道这不是OP的要求,但这是您搜索问题时Google的第一个结果。

答案 4 :(得分:1)

关闭连接会使resultSet消失。

ResultSet不是可用于传递数据的容器,它只是游标周围的包装器。您应该运行resultSet内容并将它们复制到数据结构中,然后返回数据结构。您已经这样做了,但是在关闭语句和连接之前需要这样做。

将代码更改为:

public static List<String[]> getProduttori() throws ClassNotFoundException, SQLException {

    ArrayList<String[]> res = new ArrayList<String[]>();
    /*
     * retrieve all record from produttori table
     */
    Connection conn = null;
    ResultSet rs = null;
    Statement stmt = null;
    String query = "SELECT * FROM produttore";

    conn = ConnectionManager.getConnection();
    try {
        System.out.println("Connection obtained by ProduttoreDCS class");
        stmt = conn.createStatement();
        try {
            rs = stmt.executeQuery(query);
            while (rs.next()) {
                String[] current = new String[6];
                current[0] = Integer.toString(rs.getInt("partita_iva"));
                current[1] = rs.getString("nome");
                current[2] = rs.getString("cognome");
                current[3] = rs.getString("via_sede");
                current[4] = rs.getString("citta_sede");
                current[5] = rs.getString("provincia_sede");
                res.add(current);
            }        
            return res;
        } finally {
            try {
                stmt.close();
            } catch (SQLException e) {
                log.error(e);
            }
        }
    } finally {
        try {
        conn.close();
        } catch (SQLException e) {
            log.error(e);
        }
    }        
}