Search code examples
javaspringeclipsespring-mvcderby

Error of the form: org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0


I have built a simple login page wherein I get the required row from my database using the username provided by the user and check the credentials against the user provided values.

The problem i'm facing that if the user inputs a username value that is not present in the database, I face this error

org.springframework.dao.EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

which means that my database doesn't have any row with the required username.

code:

@Controller  
public class LoginController {  
    @Autowired  
    UserDao dao;
    @RequestMapping(value="/login",method = RequestMethod.POST)  
    public ModelAndView loginResult(HttpServletRequest req,HttpServletResponse res,RedirectAttributes redir,Model model) {

    String uname=req.getParameter("username");  
    String pwd=req.getParameter("pwd");  
    String dept = req.getParameter("dept");
    LoginInfoAdmin admin = dao.getEmpById(uname); 

if(uname.equals(admin.getUsername())&&pwd.equals(admin.getPassword())&&dept.equals(admin.getDept()))
            {
                req.getSession().setAttribute("uname",admin.getName());
                if(dept.equals((String)admin.getDept())){
                    return new ModelAndView("adminLoginResult", "message", message1); 
                }
                else if(dept.equals((String)admin.getDept())){
                    return new ModelAndView("EmployeeLoginResult","message",message1);
                }
                else{
                    return new ModelAndView("ManagerLoginResut","message",message1);
                }
            } 
else
        {
            return new ModelAndView("forward:index.jsp","message","Sorry Username Password Error");
}

index page:

<body>
    <b><span class="heading">LOGIN USER</span></b>
    <div class="container">
        <form action="login.html" method="Post">
            <div class="form_style">
            <input type="text" name="username" placeholder="Enter Username"/>
            <input type="password" name="pwd" placeholder="Enter password"/>
            <select name="dept">
                <option>IT</option>
                <option>ADMIN</option>
                <option>HR</option>
                <option>MARKETING</option>
            </select>
            <input type="Submit" value="submit">
            <span class="disp">${message}</span>
            </div>
        </form>
    </div>
</body>

UserDao(wherein i used template to connect to db and fire sql)

public class UserDao {
    JdbcTemplate template;  
    public void setTemplate(JdbcTemplate template) {  
        this.template = template;  
    }  
    public LoginInfoAdmin getEmpById(String username){  
        String sql="select * from ADMINLOGINDETAILS where username=?";  
        return template.queryForObject(sql, new Object[]{username},new BeanPropertyRowMapper<LoginInfoAdmin>(LoginInfoAdmin.class));  
    }  
}

My question is how do I check whether the row is present or not after the query is fired.


Solution

  • There are a number of ways to solve your problem. One way is to catch the exception being thrown at the top level:

    try {
        LoginInfoAdmin admin = dao.getEmpById(uname);
        if(uname.equals(admin.getUsername()) && pwd.equals(admin.getPassword()) && dept.equals(admin.getDept()))
        {
            req.getSession().setAttribute("uname",admin.getName());
            if(dept.equals((String)admin.getDept())){
                return new ModelAndView("adminLoginResult", "message", message1); 
            }
            else if(dept.equals((String)admin.getDept())){
                return new ModelAndView("EmployeeLoginResult","message",message1);
            }
            else{
                return new ModelAndView("ManagerLoginResut","message",message1);
            }
        } 
        else
        {
            return new ModelAndView("forward:index.jsp","message","Sorry Username Password Error");
        }
    } catch (EmptyResultDataAccessException erdae) {
        return new ModelAndView("forward:index.jsp","message","Sorry Username Password Error");
    }
    

    Another way is to catch it lower down and return a null if the record is missing (then check for null at the top level):

    public LoginInfoAdmin getEmpById(String username){  
        try {
            String sql="select * from ADMINLOGINDETAILS where username=?";  
    
            return template.queryForObject(sql, new Object[]{username},new BeanPropertyRowMapper<LoginInfoAdmin>(LoginInfoAdmin.class));  
        } catch (EmptyResultDataAccessException erdae) {
            return null;
        }
    }
    

    Edit: It is better practice for your DAO to return an Optional<LoginInfoAdmin>. That way you can return an Optional.empty() if there was no matching record.