Jakub Fonferko
Jakub Fonferko

Reputation: 81

getCurrentSession() - NullPointerException - why?

I have a problem, when I call addCus() method in DAO file I get NullPointerException. I tried many solutions but I still get this error. Why getCurrentSession() method geterate this error and how to fix it??

pom.xml

<dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.1.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.10.Final</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.6.10.Final</version>
    </dependency>

my-servlet.xml

<mvc:annotation-driven />
<context:component-scan base-package="pl.classes"></context:component-scan>
<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass"
        value="org.springframework.web.servlet.view.JstlView"></property>
    <property name="prefix" value="/WEB-INF/views/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>


<context:property-placeholder location="mysql.properties" />

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="pl.classes.Customer" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            <prop key="hibernate.dialect">${hibernate.dialect}</prop>
    </props>
    </property>
</bean>

<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.user}" />
    <property name="password" value="${jdbc.pass}" />
</bean>

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

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

CustomerDaoImpl

public class CustomerDatabaseDaoImpl implements CustomerDatabaseDao {

@Autowired
private SessionFactory session;

private Set<Customer> customers;
private String filename;
private File file;



@Transactional
public void addCus(Customer c) {
    this.session.getCurrentSession().save(c);

}

Stack Trace

java.lang.NullPointerException
pl.dao.CustomerDatabaseDaoImpl.addCus(CustomerDatabaseDaoImpl.java:47)
pl.service.CustomerDatabaseServiceImpl.addCus(CustomerDatabaseServiceImpl.java:101)
pl.classes.CustomerDatabaseImpl.addCus(CustomerDatabaseImpl.java:76)
pl.controller.HomeController.customerList(HomeController.java:31)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:743)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:672)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:82)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:933)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:867)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:953)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:844)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:829)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

Whats wrong with my sessionFactory??

Upvotes: 4

Views: 2531

Answers (2)

SyntaX
SyntaX

Reputation: 2120

I am assuming that the line number 47 of CustomerDatabaseDaoImpl refers to this.session.getCurrentSession().save(c);

Avoid the use of new to instantiate, just in case you are using it. Spring IOC will not work with new keyword. Hence this.session.getCurrentSession() will return null.

You have not specified the details about how you are instantiating CustomerDatabaseDaoImpl. I am explaining you the right way to go about this.

@Autowired
private CustomerDatabaseDao customerDatabaseDao;

To make spring inject/autowire the dependency for CustomerDatabaseDao, it has to know a bin of the same type. It is clear from the configuration file (my-servlet.xml) that you have not defined this bean. Hence use a @Repository annotation on the CustomerDatabaseDaoImpl. @Repository should only be used on the concrete class. How to use Spring @Repository, and @Service:

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class CustomerDatabaseDaoImpl implements CustomerDatabaseDao {

    @Autowired
    private SessionFactory session;

    @Transactional
    public void addCus(Customer c) {
        this.session.getCurrentSession().save(c);
    }
}

Next important step is to specify the right package details in the configuration file. Specially only the packages of the concrete classes. If you have multiple packages, use the ',' separated values or mention only the parent package:

<context:component-scan base-package="pl.classes,pl.dao"></context:component-scan>

Similar approach should be taken for your Service classes. Annotate the concrete service classes with @Service annotations. Use @Autowire to inject the service class in your Spring Controller. Mention the package in <context:component-scan base-package="pl.classes,pl.dao,pi.service"></context:component-scan>.

Please follow this tutorial for more details: HowToDoInJava and feel free to comment for further help.

Upvotes: 1

Paweł Głowacz
Paweł Głowacz

Reputation: 3046

You have defined <context:component-scan base-package="pl.classes"></context:component-scan>.

For me it means that annotation @Autowired works only for package pl.classes. But in your log NullpointerException appears in class CustomerDatabaseDaoImpl in package pl.dao.

Question is how Spring can know about this class ?

So you need to tell spring to find that package also in your spring configuration. Add this to context:component-scan:

<context:component-scan base-package="pl.classes, pl.dao"></context:component-scan>

I have some doubt with injecting spring component in your application. Is it mix of different approaches ? @Autowired, Setter/Getter, Constructor injections ?

Upvotes: 0

Related Questions