0

Problem was: Can't get just inserted data from the table. From the error message it looks like it doesn't see the first column. I know the column is there and data was inserted. I checked database. I checked if column Number has some hidden space in name. No it doesn't.

Tried: Debugged every line and everything was good together with inserting data to database. Found the issue is almost at the end of the code:

        rs1.next();
        String s1 = rs1.getString(1);

I tried to write

        rs1.first();
        String s1 = rs1.getString(1);

or

        rs1.first();
        String s1 = rs1.getString("Number");

Below I posted my final code that is working correctly and I am able to insert data to the table and display on the browser.

    package mypackage;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Collections;
    import java.util.LinkedList;
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.PathParam;
    import javax.ws.rs.QueryParam;
    import javax.ws.rs.core.Response;

    @Path("/query")
    public class CList {

        private LinkedList<SMember> contacts;

        public CList() {
        contacts = new LinkedList();
        }

        @GET
        @Path("/{CList}")
        public Response addCLocation(@QueryParam("employeeId") String eId) throws SQLException{

            String dataSourceName = "DBname";
            String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName;
            String result = "";
            Connection con = null;
            PreparedStatement ps0 = null, ps = null;
            ResultSet rs = null, rs1 = null;
            String id = eId;

            try {
                try{
                //Database Connector Driver
                Class.forName("com.mysql.jdbc.Driver");
                //Connection variables: dbPath, userName, password
                con = (Connection)    
                        DriverManager.getConnection(dbURL,"someusername","somepassword");
                    System.out.println("We are connected to database");
                    //SQL Statement to Execute
                    System.out.print(id);
                    s = con.prepareStatement("SELECT 1 FROM CList WHERE Number=?");
                                    s.setString(1, eId);
                    rs = s.executeQuery();
                    //Parse SQL Response
                    if(!rs.next()) { 
                        SMember sm = new SMember();
                        ps = (PreparedStatement) con.prepareStatement("INSERT 
                              INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) " +
              "VALUES (?,?,?,?)");
                        ps.setString(1,sm.getEmployeeID());
                        ps.setString(2,sm.getFirstName());
                        ps.setString(3,sm.getLastName());
                        ps.setString(4,sm.getPhone());
                        ps.executeUpdate();
                                            ps = con.prepareStatement("SELECT Number, First_Name, 
                                                Last_Name, Phone_Number FROM CList 
                                                WHERE Number=" + eId);
                    rs1 = ps.executeQuery();
                    while(rs1.next()){
                        result = "[Added contact to contact list.  
                                                              Number: " + rs1.getString(1) + 
                            "][First_Name: " + rs1.getString(2) + 
                            "][Last_name: " + rs1.getString(3) +
                            "][Phone_Number: " + rs1.getString(4) +
                             "]\n";
                    }
                    }
                    else {
                        result = "[Contact is already on the list]";
                    }
                }
                catch(Exception e) {
                    System.out.println("Can not connect to database");
                    e.printStackTrace();
                }
                finally {
                    //Close Database Connection
                    ps0.close();
                    ps.close();
                    con.close();    
                }
            }
            catch(Exception e) {
                System.out.println(e);
            }
           //Return the Result to Browser
           return Response.status(1000).entity(result).build(); 
        } 

Table

enter image description here

1234 number is unique and it is a number I want to get.

You see number should be unique. So far I am taking data from the SMember class and it always insers the same data. Purpose of my question is just to ge the information I inserted few seconds ago.

Also, there is SMember class that I didn't post here and in its constructor I initialize number, first name, last name, and phone number. Testing purpose. I made all recommended changes but problem remains the same.

Cœur
  • 37,241
  • 25
  • 195
  • 267
user1282256
  • 183
  • 1
  • 6
  • 16

4 Answers4

1

You are getting this error because your first query is wrong it is returning an empty resultset.

Firstly,

rs = s.executeQuery("SELECT 1 FROM CList WHERE Number='id'");

the above line in your code is not correct it should be like this:

**rs = s.executeQuery("SELECT 1 FROM CList WHERE Number="+id);**

then the correct query will be fired to database.

Secondly,there is problem in following code

if(rs.next() == false) { 
                     SMember sm = new SMember();
                     ps = (PreparedStatement) con.prepareStatement("INSERT  
                                         INTO CList (Number, First_Name, Last_Name,  
                                         Phone_Number) VALUES ('"+sm.getEmployeeID()+"', 
                                         '"+sm.getFirstName()+"', '"+sm.getLastName()+"', 
                                               '"+sm.getPhone()+"')",   
                                     Statement.RETURN_GENERATED_KEYS);
                     ps.executeUpdate(); 

In the above code you should initialize the SMember, object currently in query they are going as null also the when you are using PreparedStatement you should use the query like this:

**ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?)",Statement.RETURN_GENERATED_KEYS);
ps.setString(1,sm.getEmployeeID());
ps.setString(2,sm.getFirstName());
ps.setString(3,sm.getLastName());
ps.setString(4,sm.getPhoneNumber());**
Mudit Shukla
  • 814
  • 2
  • 6
  • 16
  • Mudit, I have made changes you suggested but still I am getting the same error. The funny thing is that data is inserted to database. I am going directly to database to check it. – user1282256 Dec 12 '13 at 09:42
  • Data is getting inserted because this condition check is wrong if(rs.next() == false) It should be written like this if(rs.next()) In this case If block will not run and logically no record will be inserted.Because as per your code you are fetching the record from database for the ID which you are getting from function parameter. – Mudit Shukla Dec 12 '13 at 10:28
  • Do you mean this condition if(rs.next() == false)? if rs.next() can't find searched id will return false because id is not there. it tries to select some employee id. executeQuery returns resultSet but never null. – user1282256 Dec 12 '13 at 10:37
  • I mean you don't need to do if(rs.next()==false) it can be better written as if(!rs.next()) will work. And I guess its not generating any keys because of which it is returning empty result set. Check this link http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html#getGeneratedKeys() – Mudit Shukla Dec 12 '13 at 10:49
1

The Query statement maybe an issue "SELECT 1 FROM CList WHERE Number='id'",In select statement your id is taken as a String.we need to replace with value.

-->Try like this {"SELECT 1 FROM CList WHERE Number="+id},

-->One more thing "select 1 from table name" will print 1 for no of rows avail for your condition.

So my suggestion is

{"SELECT * FROM CList WHERE Number="+id}

try This!!

BlackPOP
  • 5,657
  • 2
  • 33
  • 49
  • I have tried this one too, but it work the same way. Before posting code I made printing statements and the first request worked well. – user1282256 Dec 12 '13 at 10:00
1

There is several issues here.

The solution to your question is that you do not let the database generate keys, that is why you cannot ask for the generated keys later.

Look at this line of your code:

ps = (PreparedStatement) con.prepareStatement("INSERT INTO CList (Number, First_Name, Last_Name, Phone_Number) VALUES ('"+sm.getEmployeeID()+"', '"+sm.getFirstName()+"', '"+sm.getLastName()+"', '"+sm.getPhone()+"')", Statement.RETURN_GENERATED_KEYS);

You later want to retrieve the Number column's value as a generated key. You however do pass a value for that column, namely the return value of sm.getEmployeeID(). If you pass a value, it will not get generated (assuming that this column is defined in database as being auto incremented.

Fixing this however, will not solve everything as your code has quite a lot of issues. Let me list the ones I can directly spot:

  • You initialize your variable sm by creating a new object. But you will still not have values for employee id, first name, last name or phone number as you nowhere set those values to sm (or do you do that in the default constructor?).
  • You are trying to use a prepared statement, this is good, but you are actually not doing that, this is very bad as it openes the ground for SQL injection. Instead of creating the query string like you are doing, you should use a fixed string like e.g INSERT INTO CList (Number, First_Name, Last_Name,Phone_Number) VALUES (?,?,?,?) and then set the values on the statement before executing it. That way nobody can mess with your database through that statement (read up on SQL injection, just google it to see the issue you would introduce).
  • Your employee id seems to be the eId parameter of your method. You should use that also in your select statement to see if it is already in your database (use a prepared statement here also) and in your insert statement later when the id is not already in the database.
  • If you are checking for a specific id, then insert that specific id, it is quite useless to retrieve some generated id. You already have defined your unique identifier. Use that one!

Edit: As your code is kind of a mess, I have cleaned this stuff a bit and fixed the issues that I could directly find. Check if this is helping you:

public Response addCLocation(String eId) throws SQLException {

    String dataSourceName = "DBname";
    String dbURL = "jdbc:mysql://localhost:3306/" + dataSourceName;
    String result = "";
    Connection con = null;
    Statement s = null;
    PreparedStatement ps = null;
    ResultSet rs = null, rs1 = null;
    String id = eId;

    try {
      try {
        // Database Connector Driver
        Class.forName("com.mysql.jdbc.Driver");
        // Connection variables: dbPath, userName, password
        con = DriverManager.getConnection(dbURL, "someusername", "somepassword");
        System.out.println("We are connected to database");
        s = con.createStatement();
        // SQL Statement to Execute
        System.out.print(id);
        PreparedStatement alreadyThere = con.prepareStatement("SELECT 1 FROM CList WHERE Number = ?");
        alreadyThere.setString(1, eId);
        System.out.println("0");
        // Parse SQL Response
        int i = 0;
        if (rs.next() == false) {
          SMember sm = new SMember();
          ps = con
              .prepareStatement("INSERT INTO Contact_List (Number, First_Name, Last_Name, Phone_Number) VALUES (?,?,?,?)");
          ps.setString(1, sm.getEmployeeID());
          ps.setString(2, sm.getFirstName());
          ps.setString(3, sm.getLastName());
          ps.setString(4, sm.getPhone());
          ps.executeUpdate();
        }
        else {
          result = "[Contact is already on the list]";
        }
      }
      catch (Exception e) {
        System.out.println("Can not connect to database");
        e.printStackTrace();
      }
      finally {
        // Close Database Connection
        s.close();
        ps.close();
        con.close();
      }
    }
    catch (Exception e) {
      System.out.println(e);
    }
    // Return the Result to Browser
    return Response.status(200).entity(result).build();
  }
Matthias
  • 3,582
  • 2
  • 30
  • 41
  • In my edited post I made all the necessary changes. I still want to retrieve that generated it to know how it works. It still give me the same error and would love to know how to solve it. I will aslo try to use the last point from your recommendations. – user1282256 Dec 12 '13 at 10:14
  • You did not do all the necessary changes. Your check is still not using the id parameter but the String `id`. You should use a prepared statement there to prevent sql injection. And also you still try to read generated ids which are never being generated while you still have the id already handed to you as a parameter to your `addCLocation` method. – Matthias Dec 12 '13 at 10:30
  • Added code example which really makes the necessary changes. Check with that if it getting closer to what you really need. – Matthias Dec 12 '13 at 10:39
  • I made the chages you proposed. error I get in this line alreadyThere.setString(1, eId); java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0). ........... Null pointer exception at the end – user1282256 Dec 12 '13 at 11:26
  • My bad, had a different syntax in my mind, change `"SELECT 1 FROM CList WHERE Number = :id"` to `"SELECT 1 FROM CList WHERE Number = ?"`. I'll also fix this in my answer. – Matthias Dec 12 '13 at 11:33
  • At the end I am trying to print the result this way: s1 = con.prepareStatement("SELECT 1 FROM Contact_List WHERE Number=?"); s1.setString(1, sm.getEmployeeID()); rs3 = s1.executeQuery();if(rs3.next()){ result = "[Added contact to contact list. Number: " + rs3.getString(1) + "][First_Name: " + rs3.getString(2) + "][Last_name: " + rs3.getString(3) +"][Phone_Number: " + rs3.getString(4) + "]\n"; and I get this error for the rs3.getString(1): java.sql.SQLException: Column Index out of range, 2 > 1. } – user1282256 Dec 12 '13 at 12:00
  • You select `1` from your query, why do you expect it to have the first name, name, phone number present? Also you have this information all in your method, why read it again from database? Please read a good sql tutorial which will explain all those basics. – Matthias Dec 12 '13 at 12:06
  • Thank you for your help. I wrote really good part of the code and updated it in my main post. At the end I really didn't know how to solve my problem and you just told me to look for the tutorials. For lucky I found one that explained well the last part to me. – user1282256 Dec 12 '13 at 20:30
0

"SELECT 1 FROM CList WHERE Number='id'"

It looks like you're trying to actually select records where the Number value is 'id'. That may be causing the error when you try to do the "rs.next()" command on an empty result set. Are you instead trying to do something like

"SELECT 1 FROM CList WHERE Number=' " . id . "'"? Where "id" is a variable?

pnellesen
  • 81
  • 4