简体   繁体   中英

Dependency injection with Spring fails

I am using Spring4. I have 3 classes: MyController, ADao and BDao.

viewAs() method in MyController class calls getAs() method in ADao, getAs() method from ADao calls getB() method in BDao.

SessionFactory object in ADao class get injected but sessionFactory object in BDao class does not get injected. My question is why does it not get injected? I get Null pointer exception because sessionFactory object is null in BDao class.

Is it because I am calling one dao from another dao?

@Controller
public class MyController {
    @Autowired
    private ADao aDao;

    @RequestMapping(value="viewAllItems")
    public String viewAs(HttpServletRequest req, HttpServletResponse res){
        List<Item> list = new ArrayList<Item>();
        list = aDao.getAs();
        return "";
    }
}

@Repository
public class ADao {
    @Autowired
    private SessionFactory sessionFactory;//objected gets injected. 

    public ADao(){}

    public List<A> getAs() throws HibernateException{
        session = sessionFactory.openSession();
        tx = session.beginTransaction();
        new B().getB(null);

        return null;
    }
}

@Repository
public class BDao {

    @Autowired
    private SessionFactory sessionFactory;

    private Session session;

    public BDao(){}

    public void getB(B b) throws HibernateException{
        session = sessionFactory.openSession();// Object does not get injected. Causes NullPointerException 
    }
}

EDIT: dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:context="http://www.springframework.org/schema/context"
     xmlns:p="http://www.springframework.org/schema/p"
     xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- JSR-303 support will be detected on classpath and enabled automatically -->
    <mvc:annotation-driven/>

        <context:component-scan base-package="com.karmacrafts.web.controller" />
        <context:component-scan base-package="com.karmacrafts.model.dao"/> 
        <context:property-placeholder location="classpath:application.properties" />
        <context:annotation-config/>

        <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
            <property name="viewClass"
                value="org.springframework.web.servlet.view.JstlView" />
            <property name="prefix" value="/WEB-INF/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean> 


           <bean id="sessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
              <property name="dataSource" ref="dataSource" />
              <property name="packagesToScan" value="com.karmacrafts.model.impl" />
              <property name="hibernateProperties">
                 <props>
                    <prop key="hibernate.dialect">${jdbc.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.databaseurl}" />
              <property name="username" value="${jdbc.username}" />
              <property name="password" value="${jdbc.password}" />
           </bean>

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

           <bean id="persistenceExceptionTranslationPostProcessor"
            class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>


        <bean id="ADao" class="com.ADao" />
        <bean id="BDao" class="com.BDao"/>
</beans>

Add following in the ADAO class:

**@Autowired

private BDao bdao;//objected gets injected.** 

And use this object to invoke the BDao method rather than using new operator

When you said new B() you are off from Spring Context. You have created a bean on your own which will not have anything injected from spring context. Replace new B() with context.getBean()

Or Autowire BDao in your ADao

In ADao class getAs() method, you are using new operator as

    new B().getB(null);

and it is not a spring managed bean. So autowiring will not work to get sessionFactory injected in class BDao.

Instead, you can inject BDao in ADao by autowiring as:

@Repository
public class ADao {
    @Autowired
    private BDao bdao;//use this to call getB method
    ...
}   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM