2012-06-11 161 views
3

我有以下源代碼。jdbc ResultSet關閉

在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 
} 
+1

你可以指出你的代碼是拋出異常嗎? –

回答

5

resultset可能沒有任何記錄,這就是爲什麼next()關閉它的原因。

next()返回一個布爾值,檢查它。

+0

你們真的很擅長JAVA ioi。謝謝 –

2

檢查值rs.next();它必須返回false。你需要這樣做。

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

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

轉寄此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 
1

你應該檢查什麼rs.next返回。如果是false意味着什麼都沒有被提取。

現在,如果您使用if(rs.next),那麼您只考慮ResultSet已返回的第1行。如果查詢返回的行數超過1行,並且想要考慮所有行,則使用while(rs.next)

再次,即使您在代碼上面添加while(rs.next)_code, _value, _language _locale也會包含ResultSet中返回的最後一行的值。所以你必須相應地修改你的代碼。