BustedSanta
BustedSanta

Reputation: 1388

Spring / Hibernate - NullPointerException

I am completely new to Spring (MVC) and Hibernate and I am trying to learn it.

I made up the following authentication scenario to practice but I am not having much luck getting it to work.

Scenario:

I have an HTML form (homepageForm.jsp) that sends username and password to HomeController. The HomeController gets the form parameters (username/password) and compares the form params to username & password retrieved from a database.

If there's a match, the user will be presented with the dashboard.jsp. If there's a mismatch, the error.jsp will be loaded instead.

The information from the db is retrieved by the "UserRetrievalService".

I am getting the following error:

:::: ERROR

    type Exception report

    message Request processing failed; nested exception is java.lang.NullPointerException

    description The server encountered an internal error that prevented it from fulfilling this request.

    exception
    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
        org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982)
        org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
        org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)


    root cause
    java.lang.NullPointerException
        com.springdemo.mvc.HomeController.processLoginForm(HomeController.java:91)
        sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

I suspect it's related to the way the servlet.xml is referenced. The line 91 in the HomeController is this one:

User user = userRetrievalService.getUser();

or perhaps I am using the @Autowired incorrectly.

Could anyone please give me some tips how to resolve this?

Thank you!

Here's some additional info about the project.

enter image description here

**** servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd">

        <context:component-scan base-package="com.springdemo.mvc" />
        <context:component-scan base-package="com.springdemo.model" />

        <mvc:annotation-driven/>

        <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/view/" />
            <property name="suffix" value=".jsp" />
        </bean>

    </beans>

**** web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
      <display-name>spring-mvc-demo</display-name>
      <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    </web-app>

**** homepageForm.jsp

    <html>
    <head>
    <title>Homepage Form</title>
    </head>

    <body>
        <form action="processLogin" method="POST">
            <div>
                <label>Username</label> <input type="text" name="username" placeholder="username" />
            </div>
            <div>
                <label>Password</label> <input type="text" name="password" placeholder="password" />
            </div>
            <input type="submit" value="Login" />
        </form>
    </body>

    </html>

**** User.java

    package com.springdemo.model;

    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;

    @Entity
    @Table(name = "user")
    public class User implements AbstractUser {

        @Id
        @Column(name = "id")
        private int id;

        @Column(name = "username")
        private String username;

        @Column(name = "password")
        private String password;

        @Column(name = "first_name")
        private String firstname;

        @Column(name = "last_name")
        private String lastname;

        @Column(name = "email")
        private String email;

        public User() {

        }

        public User(int id, String username, String password, String firstname, String lastname, String email) {
            super();
            this.id = id;
            this.username = username;
            this.password = password;
            this.firstname = firstname;
            this.lastname = lastname;
            this.email = email;
        }

        + getters & setters

    }

**** UserService

    public interface UserService {

        public User getUser();
    }

**** UserRetrievalService

    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.springframework.stereotype.Component;

    @Component
    public class UserRetrievalService implements UserService {

        @Override
        public User getUser() {

            System.out.println("UserRetrievalService called...");

            Configuration config = new Configuration().configure("hibernate.cfg.xml");
            config.addAnnotatedClass(User.class);

            SessionFactory sessionFactory = config.buildSessionFactory();

            // create a session
            Session session = sessionFactory.getCurrentSession();

            try {

                // start trans
                session.beginTransaction();

                // get & create user
                User user = session.get(User.class, 1);

                // commit trans
                session.getTransaction().commit();

                System.out.println("UserRetrievalService : commit successful...");

                System.out.println(" >>>> USER: " + user.getId() + " " + user.getUsername() + " " + user.getPassword() + " " + user.getFirstname() + " " + user.getLastname());

                return user;

            } finally {
                sessionFactory.close();
            }

        }

    }

**** HomeController.java

    import javax.servlet.http.HttpServletRequest;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;

    import com.springdemo.model.User;
    import com.springdemo.model.UserRetrievalService;

    @Controller
    public class HomeController { 

    ...
    private UserRetrievalService userRetrievalService;

    @Autowired
    public UserRetrievalService getUserRetrievalService() {
        return userRetrievalService;
    }

    @RequestMapping("/processLogin")
    public ModelAndView processLoginForm(HttpServletRequest request) {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        System.out.println("username : " + username);
        System.out.println("password : " + password);

        User user = userRetrievalService.getUser();

        ModelAndView modelAndView;

        if (username.equalsIgnoreCase(user.getUsername()) && (password.equalsIgnoreCase(user.getPassword()))) {
            modelAndView = new ModelAndView("dashboard"); // page to be returned
        } else {
            modelAndView = new ModelAndView("error"); // page to be returned
        }

        // System.out.println("success: user id = " + user.getId());

        modelAndView.addObject("myUser", user);

        return modelAndView;
    }
    ...
    }

::::: hibernate.cfg.xml

    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>

        <session-factory>

            <!-- JDBC Database connection settings -->
            <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="connection.url">jdbc:mysql://localhost:3306/springtestdb?useSSL=false</property>
            <property name="connection.username">*****</property>
            <property name="connection.password">*****</property>

            <!-- JDBC connection pool settings ... using built-in test pool -->
            <property name="connection.pool_size">1</property>

            <!-- Select our SQL dialect -->
            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

            <!-- Echo the SQL to stdout -->
            <property name="show_sql">true</property>

            <!-- Set the current session context -->
            <property name="current_session_context_class">thread</property>

        </session-factory>

    </hibernate-configuration>

Upvotes: 0

Views: 1191

Answers (2)

satya-j
satya-j

Reputation: 349

Your UserRetrievalService not properly injected.

You can use @Autowired or Constructor/Setter injection. In your case you used setter injection but not in a proper way

It should be like

private UserRetrievalService userRetrievalService;

@Autowired
public UserRetrievalService setUserRetrievalService(UserRetrievalService userRetrievalService) {
    this.userRetrievalService = userRetrievalService;
}

Suggestion regarding hibernate configuraion.

You need keep hibernate.cfg.xml under classpath

As yours is maven project, the ideal place would be /src/main/resources/

Please refer to https://stackoverflow.com/a/29352557/7063373 for more clarity.

Upvotes: 2

andolsi zied
andolsi zied

Reputation: 3791

According to the Javadoc for Autowired, the annotation can be used on "a constructor, field, setter method or config method". In HomeController put Autowired annotation in service field.

@Autowired 
private UserRetrievalService userRetrievalService;

Upvotes: 2

Related Questions