4

我有以下来源。

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

6 回答 6

7

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

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

于 2012-06-11T09:05:56.627 回答
2

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

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

   }
于 2012-06-11T09:08:10.413 回答
2

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

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

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

于 2012-06-11T09:17:43.737 回答
1

您不能只添加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;
    }
于 2012-06-11T09:10:00.380 回答
1

取而代之的是——

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"); 
} 
于 2012-06-11T09:10:20.223 回答
1

请参阅此页面

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
于 2012-06-11T09:11:26.120 回答