2014-05-13 71 views
0

我有這樣的代碼:未關閉的聲明快把我逼瘋了

 Helper helper = getDBhelper(); 

     Connection conn = helper.getConnection(); 

     String sql = 
       " SELECT DISTINCT date as plannedDate" + 
       " FROM plan "; 

     String AssimilationTabDates = 
       " SELECT DISTINCT payment as plannedDate " + 
       " FROM credit_mo_assimilation_tab "; 

     String assimilationInfoDates = 
       " SELECT DISTINCT planned_pay as plannedDate " + 
       " FROM assimilation "; 


     String sqlUpdate = 
       " UPDATE plan " + 
       " SET date = ? " + 
       " WHERE planned_date = ? "; 

     String updateAssimilationTab = 
       " UPDATE assimilation " + 
       " SET payment = to_date(?, 'DD-MM-YYYY') " + 
       " WHERE d_payment = to_date(?, 'DD-MM-YYYY') "; 

     String updateAssimilationInfo = 
       " UPDATE assimilation " + 
       " SET pay = to_date(?, 'DD-MM-YYYY') " + 
       " WHERE planned_pay = ? "; 



     PreparedStatement ps = null; 
     ResultSet rs = null; 
     Date plannedDate = null; 
     List<String> plannedDates = new ArrayList<String>(); 
     List<String> plannedTabDates = new ArrayList<String>(); 
     List<String> plannedInfoDates = new ArrayList<String>(); 

     try { 
      ps = conn.prepareStatement(sql); 
      ps.execute(); 
      rs = ps.getResultSet(); 

      while(rs.next()) { 
        plannedDate = rs.getDate("plannedDate"); 
        String plannedD = new SimpleDateFormat("dd-MMM-yy").format(plannedDate); 
        plannedDates.add(plannedD); 
      } 

      ps = conn.prepareStatement(AssimilationTabDates); 
      ps.execute(); 
      rs = ps.getResultSet(); 

      while(rs.next()) { 
        plannedDate = rs.getDate("plannedDate"); 
        String plannedD = null; 
        if(plannedDate != null){ 
         plannedD = new SimpleDateFormat("dd-MMM-yy").format(plannedDate); 
        } 
        if(plannedD != null){ 
         plannedTabDates.add(plannedD); 
        } 

      } 

      ps = conn.prepareStatement(assimilationInfoDates); 
      ps.execute(); 
      rs = ps.getResultSet(); 

      while(rs.next()) { 
        plannedDate = rs.getDate("plannedDate"); 
        String plannedD = new SimpleDateFormat("dd-MMM-yy").format(plannedDate); 
        plannedInfoDates.add(plannedD); 
      } 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 


     try{ 
      for(String oneItem : plannedDates) { 
       SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy"); 
       Date datePlanned = formatter.parse(oneItem); 
       Date paymentDate = datePlanned; 

       Date paymentDateReal = paymentDate; 

       if (paymentDate != null) { 

        paymentDateReal = DefaultProdCalendar.findNearestWorkingDay(paymentDate); 
      } 

      String realDate = new SimpleDateFormat("dd-MMM-yy").format(paymentDateReal); 



       ps = conn.prepareStatement(sqlUpdate); 
       ps.setString(1, realDate); 
       ps.setString(2, oneItem); 
       ps.execute(); 
       rs = ps.getResultSet(); 
      } 

      for(String oneItem : plannedTabDates) { 
       SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy"); 
       Date datePlanned = formatter.parse(oneItem); 
       Date paymentDate = datePlanned; 

       Date paymentDateReal = paymentDate; 

       if (paymentDate != null) { 
        paymentDateReal = DefaultProdCalendar.findNearestWorkingDay(paymentDate); 
      } 

      String realDate = new SimpleDateFormat("dd-MMM-yy").format(paymentDateReal); 



       ps = conn.prepareStatement(updateAssimilationTab); 
       ps.setString(1, realDate); 
       ps.setString(2, oneItem); 
       ps.execute(); 
       rs = ps.getResultSet(); 
      } 

      for(String oneItem : plannedInfoDates) { 
       SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy"); 
       Date datePlanned = formatter.parse(oneItem); 
       Date paymentDate = datePlanned; 

       Date paymentDateReal = paymentDate; 

       if (paymentDate != null) { 
        paymentDateReal = DefaultProdCalendar.findNearestWorkingDay(paymentDate); 
      } 

      String realDate = new SimpleDateFormat("dd-MMM-yy").format(paymentDateReal); 



       ps = conn.prepareStatement(updateAssimilationInfo); 
       ps.setString(1, realDate); 
       ps.setString(2, oneItem); 
       ps.execute(); 
       rs = ps.getResultSet(); 
      } 


     }catch(Exception e){ 
      e.printStackTrace(); 
     } 



     try { 
      ps = conn.prepareStatement(sql); 
      ps.execute(); 
      rs = ps.getResultSet(); 

      while(rs.next()) { 
        plannedDate = rs.getDate("plannedDate"); 
        String plannedD = new SimpleDateFormat("dd-MMM-yy").format(plannedDate); 
        plannedDates.add(plannedD); 
      } 

      ps = conn.prepareStatement(AssimilationTabDates); 
      ps.execute(); 
      rs = ps.getResultSet(); 

      while(rs.next()) { 
        plannedDate = rs.getDate("plannedDate"); 
        String plannedD = null; 
        if(plannedDate != null){ 
         plannedD = new SimpleDateFormat("dd-MMM-yy").format(plannedDate); 
        } 

        if(plannedD != null){ 
         plannedTabDates.add(plannedD); 
        } 
      } 

     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 


     try{ 
      for(String oneItem : plannedDates) { 
       SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy"); 
       Date datePlanned = formatter.parse(oneItem); 
       Date paymentDate = datePlanned; 

       Date paymentDateReal = paymentDate; 

       if (paymentDate != null) { 
        paymentDateReal = DefaultProdCalendar.findNearestWorkingDay(paymentDate); 
      } 

      String realDate = new SimpleDateFormat("dd-MMM-yy").format(paymentDateReal); 



       ps = conn.prepareStatement(sqlUpdate); 
       ps.setString(1, realDate); 
       ps.setString(2, oneItem); 
       ps.execute(); 
       rs = ps.getResultSet(); 
      } 

      for(String oneItem : plannedTabDates) { 
       SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yy"); 
       Date datePlanned = formatter.parse(oneItem); 
       Date paymentDate = datePlanned; 

       Date paymentDateReal = paymentDate; 

       if (paymentDate != null) { 
        paymentDateReal = DefaultProdCalendar.findNearestWorkingDay(paymentDate); 
      } 

      String realDate = new SimpleDateFormat("dd-MMM-yy").format(paymentDateReal); 

       ps = conn.prepareStatement(updateAssimilationTab); 
       ps.setString(1, realDate); 
       ps.setString(2, oneItem); 
       ps.execute(); 
       rs = ps.getResultSet(); 
      } 


     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
     finally { 
      try { 
      ps.close(); 
      conn.close(); 
     } catch (SQLException e) { 
      e.printStackTrace(); 
     } 
     } 

上面的代碼運行完全正常,但有一個小問題。該聲明是沒有得到關閉,所以這是推動我jboss服務器來做到這一點,它拋出了幾乎所有的查詢執行以下錯誤:

Closing a statement you left open, please do your own housekeeping: java.lang.Throwable: STACKTRACE 

是不是

ps.close(); 
conn.close(); 

finally應該關閉一切了嗎?

我知道我錯過了一些非常小而簡單的事情,但我現在無法發現它。

+4

我強烈建議使用'try-with-resources' ... –

+2

我強烈建議將其中的每一個轉換爲單獨的方法。用單一方法看到所有這些try/catch塊會讓我生病。 – duffymo

回答

8

您不斷創建新的準備好的語句並將它們分配到ps,但您只關閉最後一個語句。如果你需要執行一系列的語句,可以在執行時關閉它們,也可以將它們放在單獨的變量中,以便最後關閉它們。

0

除了chrylis說的,你的異常處理是有缺陷的。當你發現異常時,它不會傳播到封閉的try/catch。所以你應該用這個替換你的catch-clause:

} catch (Exception ex) { 
     ex.printStackTrace(); // I'd also replace this by something useful (ie. logging) 
    } finally { 
     ps.close(); 
    } 
1

如果我們同意一個方法應該做一件好事,我會說這是一個糟糕的實現。

每個SQL操作都應該有一個單獨的方法。每個try/catch/finally應該在儘可能最窄的範圍(方法範圍)內創建和關閉資源。

如果您獲取Connection,則無法提交/回滾邏輯。我建議將它傳遞到你的SQL方法。讓一個知道工作單元的服務或業務層獲取Connection並提交或回滾。

我也想說你不必要地重複了很多代碼。我會重構製作這款DRY-呃。

+0

這是很好和正確的建議,但實際上並沒有解決這個問題。 – chrylis

+0

我認爲它確實如此。單一方法中的多個實例反映了關閉這些實例的誤解。 – duffymo