The follwoing servlet snippet :
ResultSet set = statement.executeQuery();
// userName = set.getString(1);
if(set.next()) {
userName = set.getString("FirstName");
Email = set.getString("Email");
}
if(set.wasNull()) { //<<------------- line 33
// turn to the error page
response.sendRedirect("LoginFailure.jsp");
} else {
// start the session and take to his homepage
HttpSession session = request.getSession();
session.setAttribute("UserName", userName);
session.setMaxInactiveInterval(900); // If the request doesn't come withing 900 seconds the server will invalidate the session
RequestDispatcher rd = request.getRequestDispatcher("portfolio_one.jsp");
rd.forward(request, response); // forward to the user home-page
}
creates the following exceptions :
INFO: java.sql.SQLException: Invalid operation: wasNull() called with no data retrieved.
at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.client.am.SqlException.getSQLException(Unknown Source)
at org.apache.derby.client.am.ResultSet.wasNull(Unknown Source)
at com.sun.gjc.spi.base.ResultSetWrapper.wasNull(ResultSetWrapper.java:141)
--------->> at projectcodes.ValidateDataForSignIn.doPost(ValidateDataForSignIn.java:33)
..........
Why does this exception occur ? The exception occurs due to the highlighted line : 33
This exception can occur when ResultSet#next()
has returned false
. I.e. there is no row at all and thus no column has been retrieved at all. The ResultSet#wasNull()
only applies on the last retrieved column, not on the last retrieved row.
You need to rearrange your code logic.
if(set.next()) {
userName = set.getString("FirstName");
Email = set.getString("Email");
// start the session and take to his homepage
HttpSession session = request.getSession();
session.setAttribute("UserName", userName);
session.setMaxInactiveInterval(900); // If the request doesn't come withing 900 seconds the server will invalidate the session
RequestDispatcher rd = request.getRequestDispatcher("portfolio_one.jsp");
rd.forward(request, response); // forward to the user home-page
} else {
// turn to the error page
response.sendRedirect("LoginFailure.jsp");
}
More clear would be to refactor all that JDBC mess into a standalone UserDAO
DAO class with a User
model class which you then use as follows:
User user = userDAO.find(username, password);
if (user != null) {
request.getSession().setAttribute("user", user);
request.getRequestDispatcher("portfolio_one.jsp").forward(request, response);
} else {
response.sendRedirect("LoginFailure.jsp");
}
where the find()
method look something like this:
public User find(String username, String password) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
User user = null;
try {
connection = database.getConnection();
statement = connection.prepareStatement("SELECT id, username, email, firstname, lastname, FROM user WHERE username = ? AND password = MD5(?)");
statement.setString(1, username);
statement.setString(2, password);
resultSet = statement.executeQuery();
if (resultSet.next()) {
user = new User();
user.setId(resultSet.getLong("id"));
user.setUsername(resultSet.getString("username"));
user.setEmail(resultSet.getString("email"));
user.setFirstname(resultSet.getString("firstname"));
user.setLastname(resultSet.getString("lastname"));
}
} finally {
close(resultSet, statement, connection);
}
return user;
}
This way you end up with more self-documenting and better reuseable/testable code.