【问题标题】:jdbc ResultSet closedjdbc ResultSet 关闭
【发布时间】:2012-06-11 09:02:11
【问题描述】:

我有以下来源。

insertMessage(..)中调用selectMessage判断是否存在重复记录。

但是发生了这个错误。 在我的大脑中,它工作得很好,因为数据源给了我新的连接......也许

java.sql.SQLException: ResultSet closed
    at org.sqlite.RS.checkOpen(RS.java:63)
    at org.sqlite.RS.findColumn(RS.java:108)
    at org.sqlite.RS.getString(RS.java:317)
    at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:263)
    at org.apache.commons.dbcp.DelegatingResultSet.getString(DelegatingResultSet.java:263)
    at org.springframework.context.support.CachedMessageSourceDao.selectMessage(CachedMessageSourceDao.java:68)
    at org.springframework.context.support.CachedMessageSourceDao.insertMessage(CachedMessageSourceDao.java:94)
    at MessageSourceDemo.main(MessageSourceDemo.java:11)

public String selectMessage(String code, String language) {
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    String value = null;

    String sql = "SELECT code, value, language FROM " + TABLE + " where code=? and language=? and flag = '" + FLAG_OK + "'";

    try {
        conn = dataSource.getConnection();
        conn.setAutoCommit(true);
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, code);
        pstmt.setString(2, language);
        rs = pstmt.executeQuery();
        rs.next();

        String _code = rs.getString("code");
        String _value = rs.getString("value");
        String _language = rs.getString("language");
        Locale _locale = new Locale(_language);
        value = _value;

    } catch(SQLException ex) {

        ex.printStackTrace();

    } finally {

        try {
            if(rs != null);
            if(pstmt != null) pstmt.close();
            if(conn != null) conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
    return value;
}

public synchronized void insertMessage(String code, String value, String language) throws SQLException {
    //Duplicate Message Check
    **if(selectMessage(code, language) != null) throw new SQLException("Duplicate message exists for code: " + code + " and" + "language: " + language);**

    String sql = "INSERT INTO " + TABLE + " (code, value, language, flag) values (?, ?, ?, '" + FLAG_OK + "')";

    Connection conn = null;
    PreparedStatement pstmt = null;

    try {
        conn = dataSource.getConnection();
        conn.setAutoCommit(true);
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, code);
        pstmt.setString(2, value);
        pstmt.setString(3, language);
        pstmt.execute();

    } catch(SQLException ex) {

        ex.printStackTrace();

    } finally {

        try {

            if(pstmt != null) pstmt.close();
            if(conn != null) conn.close();

        } catch (SQLException e) {

            e.printStackTrace();

        }

    }

    notifyMessageChange(); //Realtime apply to MessageSource
}

【问题讨论】:

  • 您能否指出代码中抛出异常的行。

标签: java jdbc


【解决方案1】:

您的resultset 可能没有任何记录,这就是next() 关闭它的原因。

next() 返回一个布尔值,检查一下。

【讨论】:

    【解决方案2】:

    检查rs.next(); 的值,它必须返回false。你需要这样做。

       if(rs.next()){
           //get data
    
       }
    

    【讨论】:

      【解决方案3】:

      您应该检查rs.next 返回的内容。如果是false,则表示未获取任何内容。

      现在如果您使用if(rs.next),那么您只考虑ResultSet 返回的第一行。如果查询返回超过 1 行并且您想考虑所有行,请使用 while(rs.next)

      同样,即使您在代码上方添加while(rs.next)_code, _value, _language _locale 也会在ResultSet 中返回最后一行的值。所以你必须相应地修改你的代码。

      【讨论】:

        【解决方案4】:

        您不能只添加rs.next(),因为ResultSet 可以为空,因此您必须添加条件并测试next() 的结果是否为有效行,否则返回false。

        conn = dataSource.getConnection();
                conn.setAutoCommit(true);
                pstmt = conn.prepareStatement(sql);
                pstmt.setString(1, code);
                pstmt.setString(2, language);
                rs = pstmt.executeQuery();
                if (rs.next())
        
                String _code = rs.getString("code");
                String _value = rs.getString("value");
                String _language = rs.getString("language");
                Locale _locale = new Locale(_language);
                value = _value;
            }
        

        【讨论】:

          【解决方案5】:

          代替这个 -

          rs.next();
          String _code = rs.getString("code");
          String _value = rs.getString("value");
          String _language = rs.getString("language");
          

          使用这个 -

          while(rs.next()) //or use if(if there is only one row in resultset)
          {
              String _code = rs.getString("code");
              String _value = rs.getString("value");
              String _language = rs.getString("language"); 
          } 
          

          【讨论】:

            【解决方案6】:

            请参阅此page

            public boolean next()
                             throws SQLException
                Moves the cursor down one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
                ***If an input stream is open for the current row, a call to the method next will implicitly close it.*** A ResultSet object's warning chain is cleared when a new row is read.
            
                Returns:
                true if the new current row is valid; false if there are no more rows
                Throws:
                SQLException - if a database access error occurs
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-08-26
              • 2019-04-05
              • 1970-01-01
              • 1970-01-01
              • 2010-11-05
              • 2016-12-02
              • 2019-10-20
              相关资源
              最近更新 更多