null pointer exception can't be fixed - java

I'm implementing a software for a stock management system in java.I'm using MVC design pattern and i found this exception when trying to fill a JcomboBox. I want to get all the batches when a item-code is being passed into the method.so the method should return a array-list of relevant objects. but when I run this program it gave me this kinda error and it says there is empty result set. but i also tried the sql code manually in the terminal and it worked. so i can't imagine how to fix this error. i'm glad if anyone can tell me where is the problem. I tried to post my screen shots but it cannot be done as i don't have enough reputation
here is my code
String sql = "select batchNo from MainBatch where itemCode = ?";
Connection c=DBConnection.getInstance().getConnection();
PreparedStatement ps=c.prepareStatement(sql);
ps.setString(1, itemCode);
System.out.println(itemCode+" -----> item code is thiss");
ResultSet set=ps.executeQuery();
ArrayList<MainBatch> list=new ArrayList<>();
System.out.println(set.next()+" <-----result set is");
while (set.next()) {
MainBatch batch=new MainBatch(set.getString("batchNo"));
list.add(batch);
}
return list;
[

ResultSet.next() moves the result set's cursor to the next row. When you print it, before the while loop, you're losing the first row (or the only row in a single row result set). Personally, I'd just omit it, but if you have to have it, you could extract the result to a local variable:
boolean next = set.next();
System.out.println(next + " <-----result set is");
while (next) {
MainBatch batch=new MainBatch(set.getString("batchNo"));
list.add(batch);
next = set.next();
}
return list;

Remove this line.
System.out.println(set.next()+" <-----result set is");
You are calling set.next() twise, this moves the resultset pointer to next row.

Related

Getting all results from ResultSet

I am getting a ResultSet of type ArrayList<MyClass> and all is working well, except it's not getting the first item from the list.
It seems this part is actually taking the first option and using it, despite not actually doing anything with it:
if (!result.next()) {
//throw Excepion
}
Then after that I run the while (result.next()) { and populate the ArrayList.
The first item in the database is just an empty String (well a space actually), and there are n other entries. I want the blank entry there too because this fills a JComboBox and need the first entry to always remain as a blank option.
But, because of checking if (!result.next()) before the while (result.next()), it will only show from item2 onwards. If I remove the if, it will leave the blank option in the dropdown.
Just to note, this code is using a try...finally.
So my issues/queries are:
1) Would I be best off removing the if (!result.next()) and just putting in a catch for the same exception?
2) Is it possible to use the initial way I described, but keeping the first entry in the result?
3) Is there a better way to get the first entry than just having a space in the first entry in the table? (Note that if it's just literally blank, and I remove the if, it will show a tiny little option in the dropdown table.
Taking all items from ResultSet and placing them in a list goes like this:
List<MyObj> data = new ArrayList<>();
try {
stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT Id, Name, ...");
while (rs.next()) {
int id= rs.getInt("Id");
String name = rs.getString("Name");
data.add(new MyObject(id, name));
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
You do not need to check the state of rs, because the check in the header of the while loop is sufficient.
Oracle's reference
You can check this way:
if(!rs.isBeforeFirst())
rs.isBeforeFirst() returns false if the resultset contains no rows.
When you call the next() function you allways jump to the following record, you must avoid the if(!result.next()), you can use if(result != null) and then, the loop

Why does my SQL while(set.next()) skips the first element?

I execute:
select * from table_name order by column desc;
And I want to go through the items sequentially. I got the ResultSet from that and did:
while(set.next()) {
// processing code
}
Unfortunately, that skips the very first element. What's the best way to iterate through the entire ResultSet and include the very first element?
Use:
set.beforeFirst();
while(set.next()) {
// Your code
}
This will run the body of your loop once before advancing the ResultSet. You don't want to use a do loop (my previous answer) because it will throw an Exception if the query has 0 rows returned.
I know this is really old but my search hit here and after the solution didn't work for me (forward only result set) I believe the issue was never really addressed. In my case, I was doing:
jdbcTemplate.query(sql, rs -> {
while(rs.next()) {
// processRow
}
// no return statement
, args);
I then looked more closely at the method that was being called and the second argument was a "RowCallbackHandler" and not a "ResultSetExtractor" so the correct use of this code is:
jdbcTemplate.query(sql, rs -> {
// processRow
}, args);
This does the "while (rs.next())" loop for you.
I'd wager the OP was doing the same thing I was.
Your code is correct and you are not loosing any records. In the SDK Documentation for ResultSet you can read that:
"A ResultSet object maintains a cursor pointing to its current row of data. Initially the cursor is positioned before the first row. The next method moves the cursor to the next row, and because it returns false when there are no more rows in the ResultSet object, it can be used in a while loop to iterate through the result set."
Only case were you could loose records if you do a resultSet.next() before the one you are showing.
Whenever next() is called, it reads a record from result set.
if (!set.next() ) {
System.out.println("no data");
} else {
do {
//statement(s)
} while (resultSet.next());
}

JDBC.SQLServerException: The result set has no current row

So, a solution I created threw this exception: jdbc.SQLServerException: The result set has no current row on the line marked in the below code.
public String get64BitEncodedImageBySiteID(int siteID){
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection(url, userName, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT SitePicture FROM SiteTable WHERE SiteID ="+siteID );
rs.next();
// The above line has since been moved to the if statement below where you can see it commented out,
// which prevents the exception from occuring but still doesn't fix the fact that the row is not being found.
if(/*rs.next() &&*/ rs.getBytes("SitePicture")!=null){ // EXCEPTION THROWN HERE!
byte ba[] = rs.getBytes("SitePicture");
return new sun.misc.BASE64Encoder().encodeBuffer(ba);
}
else {return null;}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
The method above, in the instance the exception was thrown, is taking a genuine siteID (22379) from an Entity object pulled directly from the same table. When using System.out.println(siteID); during this method, it declared that number to still be correct, ie still 22379. I've checked directly with the SQL server by running an identical statement in SQL Server, so I know the row exists in the table, but for some reason it is not being found. Image below.
So the problem is, the ResultsSet rs is not finding the row even though I know that it's there. Does anyone have any helpful insights?
Clarification: Just to be clear, I know that the ResultsSet contains no rows and that is why I am getting the exception. I also know that putting the rs.next() into the if statement will prevent the exception (as already stated in the comments). What is puzzling me is that the fact the ResultsSet contains no rows even though a row with the ID being parsed to it verifiably does exists because I have checked it directly with the SQL server.
This turned out to be a local mistake, but I'll post the solution anyway because this situation has some educational value.
As I've learned from #Ralph's comment to this answer, eliminating "the impossible" is a good way for such problems.
After avoiding the risk of siteID being wrong (by hardcoding it), we have a following situation:
the same exact query worked in one environment, but not the other, for only one particular SiteID, 2184
it's impossible that ResultSet just doesn't work for this particular value (I claim it is, because I always assume errors are in my code, not in language libraries)
if so, the databases must differ
Adding result statements inside while loop helped in my case.
while(rs.next) {
rs.getString("your column name");
}
The most likely explanation is that your ResultSet contains no rows. Have you checked that?
If that's the case, rs.next() will return false, but you are not checking the return value any more. Put rs.next() back into the if block, it was OK in there.
You can make sure by:
if (rs.next()) {
if(rs.getBytes("SitePicture")!=null){
byte ba[] = rs.getBytes("SitePicture");
return new sun.misc.BASE64Encoder().encodeBuffer(ba);
}
} else {
System.out.println("No rows returned");
}
EDIT:
what column type is siteID?
Your method takes an int, but your SQL wraps it in quotes, as if it were a string.
EDIT 2:
Using a PreparedStatement might solve your problem.
PreparedStatement ps = conn.prepareStatement("SELECT SitePicture FROM SiteTable WHERE SiteID = ?");
ps.setInt(1, siteId);
ResultSet rs = ps.executeQuery();
You may not get the result without checking whether the result has entries. For that use
while(rs.next()){
rs.getString("column name");
}
and try it. It worked fine for me.
Thanks

Use of getters in ResultSets

I am trying to write java code to access a table 'customer' with columns 'customer_id', 'email', 'deliverable', and 'create_date'
I have
Connection conn = DriverManager.getConnection(connectionUrl, connectionUser, connectionPassword);
Statement constat = conn.createStatement();
String query = "SELECT * FROM customer WHERE customer_id LIKE " + customerId;
ResultSet rtn = constat.executeQuery(query);
Customer cust = new Customer(rtn.getInt("customer_id"), rtn.getString("email"), rtn.getInt("deliverable"), rtn.getString("create_date"));
conn.close();
return cust;
I am receiving the error:
java.sql.SQLException: Before start of result set
As far as I can tell, my error is in the line where I am creating a new Customer object, but I cannot figure out what I am doing wrong. Can anyone offer me some help? Thanks!
You must always go to the next row by calling resultSet.next() (and checking it returns true), before accessing the data of the row:
Customer cust = null;
if (rtn.next()) {
cust = new Customer(rtn.getInt("customer_id"),
rtn.getString("email"),
rtn.getInt("deliverable"),
rtn.getString("create_date"));
}
Note that you should also
use prepared statements instead of String concatenation to avoid SQL injection attacks, and have more robust code
close the connections, statements and resultsets in a finally block, or use the try-with-resources construct if using Java 7
Read the JDBC tutorial
You should call ResultSet.first() to move the result to the first position. The result set is a programming convention not to retrieve the whole result of the query and keep in memory. As such, its interface is quite low level and you must explicit select the row via methods like first(), last() or next() (each returns true to check if the requested row index is in the set)
You need to add
rtn.next();
before you use the result set.
Usually this is done as
while (rtn.next()) {
<do something with the row>
}

How to process ResultSet you know has only one record in it

I'm struggling with a homework assignment and am getting hung up on some SQL queries.
My query is interrogating an inventory database for the quantity of some item. The query requests the column with the name quantity_in_stock from the table, given the primary key.
I have initialized some prepared statements. This is the one I'm using here:
stmtFindColumn = Database.getConnection().prepareStatement(String.format("select ? from %s where %s = ?",
INVENTORY_TABLE_NAME, SKU) );
Now a separate method is called. I pass it a static const QTY_IN_STOCK, which is defined as "quantity_in_stock" and the item's SKU number, which is the primary key in the table.
private int getIntegerFromTable(String column, String key) {
int toReturn = 0;
try {
// Complete the prepared statement
stmtFindColumn.setString(1, column);
stmtFindColumn.setString(2, key);
ResultSet result = stmtFindColumn.executeQuery();
toReturn = result.getInt(column);
} catch (SQLException e) {
LOG.error(e.getMessage());
e.printStackTrace();
}
return toReturn;
}
When I run the query I get an sql exception that tells me: Invalid column name quantity_in_stock.
I have tried using a while loop processing result.next() and get the same error. I can't find any examples of how to properly get the results when you know only a single record is being returned.
Help!
EDIT: OK, I've found that part of my problem is I'm not getting a result set, where I should expect one. Any ideas?
UPDATE: I've tested my code, using a garden variety statement and a plain string query instead and it works just fine. So the problem is in my use of the prepared statement. Can someone check if I'm using the ? wildcards correctly? Thanks!
as far as i know, the column name may not be a parameter ...
DarkSquirrel42 is right -- you can't replace the column list of the select using a ? parameter marker. Instead, you can String.format that into place too, for example.
bad:
*select ? from INVENTORY_TABLE_NAME where SKU = ?
good:
select QUANTITY_IN_STOCK from INVENTORY_TABLE_NAME where SKU = ?

Categories