DD anomaly and clearing database resources: is there a clean solution?

Here is a piece of code that we all wrote:

  public CustomerTO getCustomerByCustDel (final String cust, final int del)
             throws SQLException {
         final PreparedStatement query = getFetchByCustDel ();
         ResultSet records = null;
         try {
             query.setString (1, cust);
             query.setInt (2, del);
             records = query.executeQuery ();

             return this.getCustomer (records);
         } finally {
             if (records! = null) {
                 records.close ();
             }
             query.close ();
         }
     }

If you omit the finally block, you will leave the database resources freezing, which is obviously a potential problem. However, if you do what I did here, set the ResultSet to null outside the ** try ** block, and then set it to the desired value inside the block. PMD reports a "DD Anomaly" error. In the documentation, DD anomaly is described as follows:

DataflowAnomalyAnalysis: Dataflow analysis tracks local definitions, uncertainties, and variable references on different data flow paths. From this information various problems can be detected. [...] DD - Anomaly: recently redefined variable. This is ominous, but not necessary to be a mistake.

If you declare a ResultSet outside the block without setting a value, you will correctly get the error "the variable may not have been initialized" when you run the if (records! = Null) test.

Now, in my opinion, my use here is not a mistake. But is there a rewriting method that would not trigger a PMD warning? I don’t really want to disable the PMD DataFlowAnomalyAnalysis rule, as identifying UR and DU anomalies would be really useful; but these DD anomalies make me suspect that I could do something better - and if there is no better way to do this, they are a mess (and I might need to see if I can rewrite the PMD rule)

+6
source share
2 answers

I think this is clearer:

PreparedStatement query = getFetchByCustDel(); try { query.setString(1, cust); query.setInt(2, del); ResultSet records = query.executeQuery(); try { return this.getCustomer(records); } finally { records.close(); } } finally { query.close(); } 

Also, in your version, the request does not close if records.close () throws an exception.

+2
source

I think the note about DD anomaly is more error than function
In addition, the way to free resources is a bit incomplete, for example

 PreparedStatement pstmt = null; Statement st = null; try { ... } catch (final Exception e) { ... } finally { try{ if (pstmt != null) { pstmt.close(); } } catch (final Exception e) { e.printStackTrace(System.err); } finally { try { if (st != null) { st.close(); } } catch (final Exception e) { e.printStackTrace(System.err); } } } 

In addition, this is again not the case, because you must close such resources

 PreparedStatement pstmt = null; Throwable th = null; try { ... } catch (final Throwable e) { <something here> th = e; throw e; } finally { if (th == null) { pstmt.close(); } else { try { if (pstmt != null) { pstmt.close(); } } catch (Throwable u) { } } } 
+1
source

Source: https://habr.com/ru/post/916646/


All Articles