8

我有生以来第一次遇到这个奇怪的错误,我不知道这是什么意思。我有一个类,它从 postgresql 数据库上的表中检索信息,执行一些操作并返回一个带有解析元素的数组列表:

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;   
}
4

5 回答 5

7

我通过运行错误的组合遇到了同样的问题:

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

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

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

于 2020-03-11T13:15:51.193 回答
5

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

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

连接#close

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

关闭语句时也适用。为了使您的代码正常工作,请不要关闭语句和连接,直到您获得行。

@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()

于 2013-06-28T16:00:48.113 回答
4

根据文档

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

您关闭了连接,然后您正在迭代,它为空。请读取数据然后关闭连接。

这里的一个好习惯是

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) {};
}
于 2013-06-28T16:01:19.400 回答
3

这就是问题:

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

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

特别是,从文档中ResultSet.close

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

于 2013-06-28T16:03:25.397 回答
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);
        }
    }        
}
于 2013-06-28T16:02:45.427 回答