0

I want to use SessionFactory of Hibernate with Spring (before I've done that manually) But I can't use SessionFactory in simply example Connecting to Oracle is OK:

Jan 01, 2015 5:29:21 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
INFO: HHH000232: Schema update complete

Also OK TransactionManager:

Jan 01, 2015 5:29:21 PM org.springframework.orm.hibernate4.HibernateTransactionManager afterPropertiesSet
INFO: Using DataSource [org.apache.tomcat.dbcp.dbcp.BasicDataSource@c5fac0] of Hibernate SessionFactory for HibernateTransactionManager

But when I try to get getCurrentSession(), using

SessionTest sessionTest = new SessionTest();
System.out.println("getSessionFactory() " + sessionTest.getSession());

There is error:

    SEVERE: Servlet.service() for servlet [dispatcher] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException
    at test.SessionTest.getSession(SessionTest.java:17)
    at controller.Test.index(Test.java:25)

I think that autowired is not working for test.SessionTest.java

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/test/</url-pattern>
    </servlet-mapping>

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

dispatcher-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:task="http://www.springframework.org/schema/task"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/task  
     http://www.springframework.org/schema/task/spring-task-3.0.xsd 
            http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
             http://www.springframework.org/schema/tx 
         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
            http://www.springframework.org/schema/context  
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

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

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

</beans>

applicationContext.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:task="http://www.springframework.org/schema/task"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/task  
     http://www.springframework.org/schema/task/spring-task-3.0.xsd 
            http://www.springframework.org/schema/beans  
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
             http://www.springframework.org/schema/tx 
         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
            http://www.springframework.org/schema/context  
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>test.SessionTest</value>

            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.globally_quoted_identifiers">true</prop>


            </props>
        </property>

    </bean>

    <bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url"
            value="jdbc:oracle:thin:@my.adgawegaw.us-east-1.rds.amazonaws.com:1521:ORCL" />
        <property name="username" value="*****" />
        <property name="password" value="*****" />

    </bean>


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

test.SessionTest.java

package test;

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

@Repository
public class SessionTest {

    @Autowired
    private SessionFactory sessionFactory;

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

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    public SessionTest() {
        System.out.println("Test created!");
    }

}

controller.Test.java

package controller;

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

import test.SessionTest;

@Controller
public class Test {

    @RequestMapping("/test/")
    public ModelAndView index( //
            ModelMap map, Model m //
    ) {


        ModelAndView mav = new ModelAndView();
        mav.setViewName("test");


        SessionTest sessionTest = new SessionTest();
        System.out.println("getSessionFactory() " + sessionTest.getSession());


        return mav;
    }

}
Artik
  • 153
  • 4
  • 14

1 Answers1

2

Spring autowires the bean instances that it controls and instantiates. It doesn't autowire objects that you create yourself. When you do

new SessionTest();

you're not asking Spring for a bean. You're creating a plain old Java object by yourself, and Spring is not aware of it, and has thus no way to autowire the dependencies of this object.

Instead of creating the SessionTest object, you should get it from Spring. And since Spring is the one instantiating the controller where you use SessionTest, you can autowire SessionTest inside the controller:

@Controller
public class Test {

    @Autowired
    private SessionTest sessionTest;

    @RequestMapping("/test/")
    public ModelAndView index(ModelMap map, Model m) {
        System.out.println("getSession() " + sessionTest.getSession());
        ...
    }
}
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255