1

I use spring 3.2.8, hibernate 4. I have an error "HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException"

exception 
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:965)
...

root cause 
java.lang.NullPointerException
    journeys.dao.CompanyDAO.f(CompanyDAO.java:41)
    journeys.controller.CompanyController.list(CompanyController.java:17)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...

web.xml:

<web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 <display-name>journeys</display-name>

 <servlet>
    <servlet-name>journeys</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>journeys</servlet-name>
        <url-pattern>/</url-pattern>
  </servlet-mapping>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/journeys-servlet.xml</param-value>
  </context-param>

  <listener>
       <listener-class>
          org.springframework.web.context.ContextLoaderListener
       </listener-class>
  </listener>

  <jsp-config>
    <jsp-property-group>
        <url-pattern>*.jsp</url-pattern>
        <page-encoding>UTF-8</page-encoding>
    </jsp-property-group>
  </jsp-config>
</web-app>

journeys-servlet.xml:

<beans xmlns="...">

    <context:component-scan base-package="journeys" />

    <bean id="viewResolver"
        ...
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://myserver:3306/name" />
        <property name="username" value="user" />
        <property name="password" value="password" />
    </bean>

    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="txManager222"
        class="journeys.dao.CompanyDAO">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <tx:annotation-driven transaction-manager="txManager" />

    <mvc:resources mapping="/resources/**" location="/resources/" />
    <mvc:annotation-driven />
</beans>

class/hibernate.cfg.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!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>
      <!-- Mapping files -->
        <mapping class="journeys.entity.Company"/>
        ....
    </session-factory>
</hibernate-configuration>

CompanyDAO:

package journeys.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;

import journeys.utils.Pair;
import journeys.entity.Company;
import journeys.entity.Journey;
import journeys.entity.JourneyDeparture;
import journeys.entity.Order;

public class CompanyDAO extends AbstractDAO<Company> {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }


    public CompanyDAO() {
        super(Company.class);
    }

    @SuppressWarnings("unchecked")
    public List<Company> f() {
        return (List<Company>)sessionFactory.getCurrentSession().createCriteria(Company.class).list();
    }
}

CompanyController:

package journeys.controller;

import journeys.dao.CompanyDAO;

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

@Controller
@RequestMapping(value = "/company")
public class CompanyController {    
    @RequestMapping(value = {"", "/", "list"}, method = RequestMethod.GET)
    public ModelAndView list() {
        ModelAndView model = new ModelAndView("Company/list");
        CompanyDAO companydao = new CompanyDAO();
        model.addObject("companies", companydao.f());

        return model;
    }
}

What am I doing wrong?

zodiac
  • 353
  • 3
  • 18
  • did you forget @Resource for private SessionFactory sessionFactory in CompanyDAO? – Cyril Deba Apr 26 '14 at 11:17
  • I added @Resource before private SessionFactory sessionFactory, but no effect. – zodiac Apr 26 '14 at 11:25
  • In your controller you are creating a new instance of the `CompanyDAO` instead of injecting the one created by spring. Hence no injection takes place and your `SesionFactory` is null. Inject the dao into your controller. – M. Deinum Apr 26 '14 at 12:27

2 Answers2

2

Your Controller code is incorrect. CompanyDAO companydao = new CompanyDAO(); is not correct. Instead of creating an instance of CompanyDAO inject it in. See the below code:

package journeys.controller;

import journeys.dao.CompanyDAO;

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

@Controller
@RequestMapping(value = "/company")
public class CompanyController {
    @Autowired
    CompanyDAO companydao ;
    @RequestMapping(value = {"", "/", "list"}, method = RequestMethod.GET)
    public ModelAndView list() {
        ModelAndView model = new ModelAndView("Company/list");

        model.addObject("companies", companydao.f());

        return model;
    }
    public void setCompanydao(CompanyDAO companydao) {
        this.companydao = companydao;
    }


}
AdityaKeyal
  • 1,208
  • 8
  • 14
  • 1
    You can also replace `@Autowired` on the private CompanyDAO variable with `@Resource(name="txManager222")` – AdityaKeyal Apr 26 '14 at 11:31
  • Now error is "org.hibernate.HibernateException: createCriteria is not valid without active transaction". Should spring do beginTransaction()? – zodiac Apr 26 '14 at 11:33
  • Just add `@Transactional` annotation to the f() method. – AdityaKeyal Apr 26 '14 at 11:34
  • Added: @Transactional @SuppressWarnings("unchecked") public List f() ..., but no effect. – zodiac Apr 26 '14 at 11:38
  • 1
    hmm.. for once try `Transaction tx = session.beginTransaction();` before criteria. Ill check why the annotation is not working. – AdityaKeyal Apr 26 '14 at 11:39
  • Maybe I wrote "context:component-scan base-package" incorrect and because of this annotation doesn't work? – zodiac Apr 26 '14 at 12:17
  • You will need to inject an instance of `HibernateTemplate` instead of `SessionFactory` for the transaction to work. The Template will basically allow spring to NOT create a new connection instead manage it internally. look more at this [url](http://forum.spring.io/forum/spring-projects/data/6628-hibernatetemplate-and-transactions) – AdityaKeyal Apr 26 '14 at 12:21
  • But [there](http://stackoverflow.com/questions/18002768/why-hibernatetemplate-isnt-recommended) advise to use SessionFactory. Is it not correct? – zodiac Apr 26 '14 at 12:28
  • That is also a valid situation since you are using Hibernate4. Hmm.. I am a little surprised that the @Transactional did not work. coz things look good. otherwise. sorry can;t help you more with this one. – AdityaKeyal Apr 26 '14 at 12:32
1

Debug this, and split up some calls. For instance, you have

return (List<Company>)sessionFactory.getCurrentSession().createCriteria(Company.class).list();

Create the criteria, then get the session, then get the list, or whatever. You can test for null at each point, or you can just step through it in a debugger at that point and find out which one results in null. One problem with long lists of calls like that is not only crashing if you get a null, but not knowing which call caused the problem when you do.

arcy
  • 12,845
  • 12
  • 58
  • 103