Menu

#1514 [java] False positive when ResultSet.wasNull() is used

New Tickets
wont-fix
None
PMD
3-Major
Bug
5.5.1
Optimization / PrematureDeclaration
2017-01-09
2016-08-17
No
import java.sql.ResultSet;
import java.sql.SQLException;

public final class JdbcUtils {

    public static Integer getInteger(final ResultSet resultSet, final String fieldName) throws SQLException {
        final int value = resultSet.getInt(fieldName);
        if (resultSet.wasNull()) {
            return null;
        }

        return value;
    }

}
$ ./pmd-bin-5.5.1/bin/run.sh pmd -d example -R java-optimizations -f csv
"Problem","Package","File","Priority","Line","Description","Rule set","Rule"
"1","","/home/coder/example/JdbcUtils.java","3","7","Avoid declaring a variable if it is unreferenced before a possible exit point.","Optimization","PrematureDeclaration"

But it's not an error, because I can't declare variable later. I have to invoke ResultSet.getInt() first and later check whether it was NULL or not with ResultSet.wasNull() method.

Discussion

  • Andreas Dangel

    Andreas Dangel - 2016-11-04
    • status: open --> more-info-needed
    • Milestone: PMD-5.5.2 --> New Tickets
     
  • Andreas Dangel

    Andreas Dangel - 2016-11-04

    Hi,
    you could write it in a different way and avoiding multiple returns, too:

    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public final class JdbcUtils {
        public static Integer getInteger(final ResultSet resultSet, final String fieldName) throws SQLException {
            Integer value = resultSet.getInt(fieldName);
            if (resultSet.wasNull()) {
                value = null;
            }
            return value;
        }
    }
    

    Would that work for you?

    I'm actually trying to avoid adjusting the rule PrematureOptimization with too specific cases like this one for ResultSet...

    Regards,
    Andreas

     
  • Slava Semushin

    Slava Semushin - 2016-12-27

    Here I've shown a bit simplified code. In reality I'm not returning this value as-is but modifying it and this means that I should add another if for checking for null again.

     
  • Andreas Dangel

    Andreas Dangel - 2017-01-08

    Can you post the not-simplified-code, please? It's hard for me to understand your use case otherwise...

     
  • Andreas Dangel

    Andreas Dangel - 2017-01-09
    • status: more-info-needed --> wont-fix
    • assigned_to: Andreas Dangel
     
  • Andreas Dangel

    Andreas Dangel - 2017-01-09

    Thanks for your patience. I've got it now.
    However, I don't think, we should change the rule for this use case. We currently have no exceptions for this rule and I'm hesitating to start adding a list of allowed violations (which could grow over time...)

    Here are three workarounds/alternatives:

    1. Since ResultSet.getInt(String) never returns null (it returns 0 if the column was NULL), we could just rely on autoboxing:
            Integer value = resultSet.getInt(fieldName);
            if (resultSet.wasNull()) {
                value = null;
            }
    
            return value;
    
    1. Or we could explicitly convert it to an Integer reference type:
            Integer value = Integer.valueOf(resultSet.getInt(fieldName));
            if (resultSet.wasNull()) {
                value = null;
            }
    
            return value;
    
    1. Using the ternary operator
            int value = resultSet.getInt(fieldName);
            return resultSet.wasNull() ? null : Integer.valueOf(value);
    

    Or you could leave your implementation just as-is with the suppression in place. Remember, not all rules of PMD can be applied to every use case - sometimes, there are good reasons to violate rules - and here the JDBC API makes it necessary to have this specific call flow.

    Therefore I'm closing this issue as "won't fix".

     

Log in to post a comment.