java jdbc 结果集关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10977064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 03:17:45  来源:igfitidea点击:

jdbc ResultSet closed

javajdbc

提问by Patrick Jeon

I have following source.

我有以下来源。

In insertMessage(..), it calls selectMessage to check whether duplicate record exists or not.

在 insertMessage(..) 中,它调用 selectMessage 来检查是否存在重复记录。

But this error occurs. In my brain, it works fine because datasource gives me new Connection...maybe

但是会出现这个错误。在我的大脑中,它工作正常,因为数据源给了我新的连接......也许

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
}

回答by Denys Séguret

Your resultsetprobably didn't have any record, which is the reason why next()closed it.

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

next()returns a boolean, check it.

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

回答by JHS

You should check what rs.nextreturns. If it is falsemeans nothing was fetched.

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

Now if you use if(rs.next)then you are considering only the 1st row that the ResultSethas returned. If the query returns more than 1 rows and you want to consider all the rows then use while(rs.next).

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

Again even if you add while(rs.next)above your code then the _code, _value, _language _localewould have the values of the last row returned in the ResultSet. So you have to modify your code accordingly.

同样,即使您while(rs.next)在代码上方添加,_code, _value, _language _locale也将在ResultSet. 所以你必须相应地修改你的代码。

回答by ejb_guy

Check the value of rs.next();It must be returning false. You need to do this.

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

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

   }

回答by Simon Dorociak

You cannot only add rs.next()because ResultSetcan be empty so you have to add condition and tests if result of next()is valid row, else it returns false.

您不能只添加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;
    }

回答by Addicted

In place of this -

代替这个 -

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

Use this -

用这个 -

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"); 
} 

回答by Akhi

Refer this 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