views:

107

answers:

4

I have this method but in run-time it will be thrown nullpointerexception,why?

my method:

public static boolean isAddBirth(String name, String family, String fatherName, String mName, String dOfBirth, String pOfBirth) {
    ResultSet rst;
    boolean bool = false;
    Statement stmt;
    try {
        stmt = conn.createStatement();



        rst = stmt.executeQuery("SELECT * FROM birthtable");


        while (rst.next()) {
            if (rst.getString(2).equals(name) && rst.getString(3).equals(family) && rst.getString(4).equals(fatherName) && rst.getString(5).equals(mName) && rst.getString(6).equals(dOfBirth) && rst.getString(7).equals(pOfBirth)) {
                bool = false;
            } else {
                bool = true;
            }
        }
    } catch (SQLException ex) {
        Logger.getLogger(Manager.class.getName()).log(Level.SEVERE, null, ex);
    }
    return bool;




}

stacktrace:

java.lang.NullPointerException
    at database.Manager.isAddBirth(Manager.java:164)
    at AdminGUI.AddNewBornInformation.submit(AddNewBornInformation.java:356)
    at AdminGUI.AddNewBornInformation.setButtonActionPerformed(AddNewBornInformation.java:283)
    at AdminGUI.AddNewBornInformation.access$800(AddNewBornInformation.java:28)
    at AdminGUI.AddNewBornInformation$9.actionPerformed(AddNewBornInformation.java:140)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
    at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
    at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
    at java.awt.Component.processMouseEvent(Component.java:6038)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
    at java.awt.Component.processEvent(Component.java:5803)
    at java.awt.Container.processEvent(Container.java:2058)
    at java.awt.Component.dispatchEventImpl(Component.java:4410)
    at java.awt.Container.dispatchEventImpl(Container.java:2116)
    at java.awt.Component.dispatchEvent(Component.java:4240)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
    at java.awt.Container.dispatchEventImpl(Container.java:2102)
    at java.awt.Window.dispatchEventImpl(Window.java:2429)
    at java.awt.Component.dispatchEvent(Component.java:4240)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

ALSO these are in my class:

Logger logger = Logger.getLogger(this.getClass().getName());
private static Connection conn = DBManager.getConnection();
+2  A: 

First of all, even if it were working, that code wouldn't do what you wanted it to. Not even close.

Second, it would help if we knew what line the exception was on. In lieu of that, though, we can narrow it down to one of the following:

  1. conn is null.
  2. conn.createStatement(); returns null.
  3. stmt.executeQuery() returns null.
  4. One of the rst.getString()s returns null.

I'm sure you can figure it out from there.

Anon.
About 3. As per API documentation this method call should never return null.http://java.sun.com/j2se/1.4.2/docs/api/java/sql/Statement.html#executeQuery(java.lang.String).
sateesh
Alright. So that means it's one of the others.
Anon.
+2  A: 

Given you didn't provide line number 164 I'll take a guess that it is:

if (rst.getString(2).equals(name) && rst.getString(3).equals(family) && rst.getString(4).equals(fatherName) && rst.getString(5).equals(mName) && rst.getString(6).equals(dOfBirth) && rst.getString(7).equals(pOfBirth))

First off that line makes me want to cry.

Let's fix it:

String a;
String b;
String c;
String d;
String e;
String f;

a = rst.getString(2);
b = rst.getString(3);
c = rst.getString(4);
d = rst.getString(5);
e = rst.getString(6);
f = rst.getString(7);

if (!(a.equals(name))
{
    bool = false;
}

if(!(b.equals(family))
{
    bool = false;
}

if(!(c.equals(fatherName))
{
    bool = false;
}

if(!(d.equals(mName))
{
    bool = false;
}

if(!(e.equals(dOfBirth))
{
    bool = false;
}

if(!(f.equals(pOfBirth))
{
    bool = false;
}

That will at least show you the line that has the null pointer on it (assuming my guess is correct).

Also, a-e are terrible names... you should pick better ones than I did.

The real solution here is to use Object Oriented programming as it is intended... let's make a Person class:

public class Person
{
    private final String firstName;
    private final String lastName;
    private final String middleName; // guessing that is what mName is...
    private final String fathersName;
    private final String dateOfBirth;
    private final String placeOfBirth; // guessing that is what pOfBirth is...

    public Person(final String firstName,
                  final String lastName,
                  final String middleName,
                  final String fathersName,
                  final String dateOfBirth,
                  final String placeOfBirth)
    {
        if(firstName == null)
        {
            throw new IllegalArgumentException("firstName cannot be null");
        }

        if(lastName == null)
        {
            throw new IllegalArgumentException("lastName cannot be null");
        }

        ... etc for all of the other arguments ...

        // I would never do the this.fristName thing.. .I would name the parameter different than the instance vairable...
        this.firstName = firstName;
        this.lastName  = lastName;

        ... etc for all of the other arguments ... 
    }

    public boolean equals(final Object o)
    {
        final Person person;

        if(!(o instanceof Person))
        {
            return (false);
        }

        other = (Person)o;

        // the code you I put above + your code for checking if they are equal
    }

    public int hashCode()
    {
        // this is probably good enough
        return (firstName.hashCode() + lastName.hashCode());
    }
}

Then in your method you would have code something like:

rst = stmt.executeQuery("SELECT * FROM birthtable");

    while (rst.next()) 
    {
        final Person person;

        // I would use temp variables rather than passing in the result of getString directly...
        person = new Person(rst.getString(2),
                            rst.getString(3),
                            rst.getString(4),
                            rst.getString(5),
                            rst.getString(6),
                            rst.getString(7));

        // otherPerson would be passed into the method instead of the String you are passing now
        bool = person.equals(otherPerson);

        ... etc ...
    }
TofuBeer
You know, you could pretty much halve the size of that code by initializing the variables on the same line they are declared and moving the opening braces to the end of the line rather than putting them on the line below.
Anon.
And removing the braces entirely and removing the extra set of brackets in each "if"...
LorenVS
it return NP exception again for the first if,:(((
Johanna
I wouldn't write the code like that to begin with (editing my answer). I do always use the { and } on their own lines... I try to keep my methods small - about 10 lines of code per method... and about 20 lines of horizontal space. Making it take more space shows me whan I have done way too much in a method.
TofuBeer
if you are getting a null pointer on the first line then it is because the rst.getString is empty... presumably because it selected no data. Try adding a System.out.println(rst) to see (JDBC isn't really my thing so debugging advice specific to that is limited :-)
TofuBeer
ok,thanks,the problem has been solved:)
Johanna
@Anon I never (save one case - ints used in a switch, and then only because the compiler forces it) init a variable where it is declared. I value consistency above pretty much everything, and since some variables cannot be initialized where declared none should be. Also if you do that and the brace moving etc... you falsely make the method look smaller than it is... and I like (very) small methods.
TofuBeer
I would argue that excessive boilerplate should be avoided. By adding lines consisting solely of braces, you're making the method look exceptionally large and complex when really it isn't. Similarly for declaring local variables and then immediately initializing them on a separate line. Useless boilerplate like that means you fit less useful information on the screen at a time, which generally decreases productivity.
Anon.
Actually I would say that method is large and complex and deserves to stand out. Something with 7 variables is complex. Like I said my code tends to be about 10 executable lines and a total length of about 20 screen lines including whitespace lines and { } pairs. An example is at https://chaos.bcit.ca/svn/public/astar/ I should probably refactor the double for loops in the Maze class too to make them smaller.
TofuBeer
+1  A: 

I think the likely cause is that the "getString" method is returning null.
The API documentation of this method indicates that it can return null.

String getString(int columnIndex) [...]

Returns: the column value; if the value is SQL NULL, the value returned is null

The above API doc reference is from: ResultSet

sateesh
A: 

For your program to be less prone to NullPointerExceptions, you could assume that the your input variables are not null (or ensure that in the beginning of your method), and the invert the comparation:

if (name.equals(rst.getString(1)) && ...

The other alternative, which I don't have any problems with, is to use the method ObjectUtils.equals(obj1, obj2) from the commons-lang library, it will return true only if both objects are null or if obj1.equals(obj2), every other possibility will return false. The classes ObjectUtils and StringUtils have a lot of methods that are null-safe, it's worth taking a look.

Ravi Wallau