2012-06-11 2 views
3

다음 소스가 있습니다.jdbc ResultSet closed

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를 리턴해야합니다. 당신은 이것을해야합니다. 당신이 next()의 결과가 유효한 행의 경우 조건 및 테스트를 추가 할 수 있도록

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

    } 
1

만 그렇지 않으면 false를 반환, 비어있을 수 rs.next()ResultSet 때문에 추가 할 수 없습니다. 이 대신에

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이 반환 한 첫 번째 행만 고려하고있는 것입니다. 쿼리가 두 개 이상의 행을 반환하고 모든 행을 고려하려면 while(rs.next)을 사용하십시오.

코드 위에 while(rs.next)을 더하더라도 _code, _value, _language _localeResultSet에 반환되는 마지막 행의 값을 갖습니다. 따라서 코드를 적절하게 수정해야합니다.