2016-07-15 20 views
0

Versuchen mit recources gibt mir folgende Ausnahme:Reusing PreparedStatement verursacht SQLException

java.sql.SQLException: Operation nicht erlaubt nach ResultSet

geschlossen

Mein Code:

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

Fügen Sie bitte die GESAMTE, COMPLETE Stack-Ablaufverfolgung ein, und identifizieren Sie auch die Zeile in Ihrem Code, der die Ausnahme auslöst. Ohne diese Basisinformationen kann Ihnen niemand helfen. –

+0

Mit Ressourcen versuchen Schließen Sie die geöffneten Ressourcen automatisch, wenn der try-Block fertig ist. – pahan

+0

@pahan: Obwohl das stimmt, ist es für das obige nicht relevant. Das OP greift nicht auf diese ResultSets zu (und kann nicht darauf zugreifen), nachdem das Try-with-resources das getan hat. –

Antwort

4

Executing Eine zweite Abfrage auf PreparedStatement schließt implizit die ResultSet aus der vorherigen Abfrage. Von Statement:

standardmäßig nur ein ResultSet Objekt pro Statement Objekt kann zur gleichen Zeit geöffnet sein.

Verwenden Sie zwei unterschiedliche Aussagen, etwas in dieser Richtung (beachten Sie, wie resultSet1 abgerufen wird), obwohl ich weiß natürlich nicht, was die Anforderungen Ihrer FOUND_ROWS Funktion sind:

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

Auch : Verwenden Sie nicht Statement 's executeQuery(String) auf PreparedStatement. Es sollte wirklich nicht da sein, es ist ein Fehler in der java.sql Verpackungsdesign. In der Tat, sagt die Dokumentation für Statement#executeQuery:

Hinweis: Diese Methode kann nicht auf einem PreparedStatement oder CallableStatement aufgerufen werden.