2016-07-15 77 views
0

嘗試的recources給了我以下異常:重複使用PreparedStatement的原因的SQLException

值java.sql.SQLException:不允許操作的ResultSet關閉

我的代碼之後:

public Set<Tablet> viewAllTablets(int offset, int noOfRecords) throws OutOfRangeException { 
    Set<Tablet> tabletSet = new HashSet<>(); 
    Tablet tablet = null; 

    try(Connection connection = dataSource.getConnection(); 
     PreparedStatement preparedStatement = connection.prepareStatement("SELECT SQL_CALC_FOUND_ROWS * FROM tablets limit " + offset + ", " + noOfRecords + ";"); 
     ResultSet resultSet = preparedStatement.executeQuery(); 
     ResultSet resultSet1 = preparedStatement.executeQuery("SELECT FOUND_ROWS()");){ 

     while (resultSet.next()){ 
      tablet = new Tablet(); 
      tablet.setTabletId(resultSet.getInt("idTablet")); 
      tablet.setName(resultSet.getString("name")); 
      tablet.setNeedRecepie(resultSet.getBoolean("need_recipe")); 
      tablet.setPrice(resultSet.getDouble("price")); 
      tablet.setTypeId(resultSet.getInt("type_id")); 
      tablet.setDescription(resultSet.getString("description")); 
      tablet.setTabletType(TypeFactory.getType(tablet.getTypeId())); 
      tablet.setWeight(resultSet.getDouble("weight_of_pack")); 
      tablet.setPillsCount(resultSet.getInt("pills_count")); 
      tabletSet.add(tablet); 
     } 
     if(resultSet1.next()) 
      this.noOfRecords = resultSet1.getInt(1); 
    } catch (SQLException e) { 
     e.printStackTrace(); 
    } 
    return tabletSet; 
} 
+0

請包含ENTIRE,COMPLETE堆棧跟蹤,並在您的代碼中標識引發異常的行。沒有這些基本的信息,沒有人能幫助你。 –

+0

嘗試使用資源自動關閉打開的資源,當try塊完成 – pahan

+0

@pahan:雖然這是真的,但它與上述無關。在資源嘗試完成後,OP不訪問(也不能訪問)這些ResultSet。 –

回答

4

執行PreparedStatement上的第二個查詢隱式關閉前一個查詢中的ResultSet。從Statement

默認情況下,每Statement只有一個ResultSet對象對象可以是在同一時間打開。

使用兩種不同的報表,這些方針的東西(注意如何resultSet1檢索),雖然我當然不知道你FOUND_ROWS功能的需求是什麼:

try (
    Connection connection = dataSource.getConnection(); 
    PreparedStatement preparedStatement = connection.prepareStatement("SELECT SQL_CALC_FOUND_ROWS * FROM tablets limit " + offset + ", " + noOfRecords + ";"); 
    ResultSet resultSet = preparedStatement.executeQuery(); 
    ResultSet resultSet1 = connection.createStatement().executeQuery("SELECT FOUND_ROWS()"); // **** 
    ) { 
    while (resultSet.next()) { 
     tablet = new Tablet(); 
     tablet.setTabletId(resultSet.getInt("idTablet")); 
     tablet.setName(resultSet.getString("name")); 
     tablet.setNeedRecepie(resultSet.getBoolean("need_recipe")); 
     tablet.setPrice(resultSet.getDouble("price")); 
     tablet.setTypeId(resultSet.getInt("type_id")); 
     tablet.setDescription(resultSet.getString("description")); 
     tablet.setTabletType(TypeFactory.getType(tablet.getTypeId())); 
     tablet.setWeight(resultSet.getDouble("weight_of_pack")); 
     tablet.setPillsCount(resultSet.getInt("pills_count")); 
     tabletSet.add(tablet); 
    } 
    if (resultSet1.next()) 
     this.noOfRecords = resultSet1.getInt(1); 
} catch (SQLException e) { 
    e.printStackTrace(); 
} 

而且:請勿在PreparedStatement上使用StatementexecuteQuery(String)。它真的不應該在那裏,它是包裝設計中的一個缺陷。事實上,Statement#executeQuery該文件說:

注意:此方法不能在PreparedStatementCallableStatement調用。