Autowired class is null

12,017

First idea : in servlet-context.xml, you have written:

<context:component-scan base-package="com.******.web.controller" />

This means that Spring will look for your annotated classes (like @Service and others) only inside this folder. Did you, by any chance, put your DAO outside of the "com.******.web.controller" folder? This would explain why it remains null.

A simple test is to use "com.******" to make sure that every folders are scanned.

Second idea : if you want that Spring instanciates your DAO class, you have to add the @Repository annotation in your concrete implementation of the DAO interface.

Third idea : you should not use XML-configuration and an annotation for the same class. In your example, you don't need to use <bean id ="exService" class= "com.*****.web.service.exampleService"></bean > if you use @Service in the exampleService class and your <component-scan> covers the directory where the service is.

Final note: You write in the comments that using @Service("exService") solved your problem. This is due to the fact that, if you don't specify the name of your components, Spring looks up for any existing bean with the given type (and not its name). So, it injected the bean you declared in XML, which had a null DAO.

To avoid this kind of problems, you should always explicitly name your beans after the name of the variable where you use it, here @Service("exService") toggles the "bind by name" behaviour, which makes your code works as expected:

// This works because the name of the variable
// matches the @Service("exService") annotation
@Autowired
private ExampleService exService;

Thanks go to @RohitJain for this last note.


Unrelated to your problem, Java classes and interfaces should always be written with an uppercase letter (e.g. "ExampleDao", "ExampleDaoImplement" and "ExampleService").

Share:
12,017
hina10531
Author by

hina10531

Senior research engineer at Tripod studio, MMORPG Lostark platform development team. Former senior research engineer at a face recognition lab. Former research engineer at a CRM application R&amp;D team.

Updated on June 04, 2022

Comments

  • hina10531
    hina10531 almost 2 years

    SUMMARY

    I'm building a spring-mvc web application and trying to use Mybatis and DAO for data access.

    I configured Mybatis successfully and I was able to fetch expected data from Mysql server.

    But a problem occured when I tried to use DAO with Mybatis.

    ERROR

    As you could see below, it's a NullPointerException.

    INFO : com.*****.web.controller.ExampleController - testDaoSelect action has been executed. No parameter has been taken.
    INFO : com.*****.web.service.exampleService - Executed or not??
    09, March, 2015 5:07:28 PM org.apache.catalina.core.StandardWrapperValve invoke
    Fatal: Servlet.service() for servlet [appServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
    java.lang.NullPointerException
        at com.*****.web.service.exampleService.sampleList(exampleService.java:29)
        at com.*****.web.controller.ExampleController.testDaoSelect(ExampleController.java:188)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:644)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
        at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
    

    REPRODUCING ERORR

    Starting with AJAX call.

        $('#DaoSelectTest').click(function(e) {
        $.ajax({
            type: "POST",
            url: "/testDaoSelect.fst",
            data: {},
            success: function (result) {
                console.log(result);
    
                var html = "Querying was successful. Check out console logs. <br/>";
                html += "Done with the test. <a href='/daoSample.fst'>Click here</a> ";
                html += "And proceed to the next.";
    
                $('#sampleTable').html(html);
            },
            error: function (result) {
                // error...
            }
        });
    });
    

    And next, the action is executed..

    @Controller
    public class ExampleController {
    
        // Mybatis direct
        @Autowired
        private SqlSession sqlSession;
    
        // Dao  
        @Autowired
        private exampleService exService;
    .
    .
    .
    .
    .
    
    
    @RequestMapping("/testDaoSelect")
            @ResponseBody
            public List<HashMap<String, Object>> testDaoSelect(HttpServletRequest request, HttpServletResponse response) {
                logger.info("testDaoSelect action has been executed. No parameter has been taken.");
    
                List<HashMap<String, Object>> result = exService.sampleList();
    
                logger.info("result size is... " + result.size());
    
                return result;
            }
    

    Calling textDaoSelect is alright, and what's next is Service class.

    @Service
    @Transactional
    public class exampleService {
    
        private Log logger = LogFactory.getLog(this.getClass());
    
        @Autowired
        private exampleDao exDao;
    
        @Transactional(readOnly = true)
        public List<HashMap<String, Object>> sampleList() {
            logger.info("Executed or not??");
    
            return exDao.sampleList();
        }
    }
    

    BOOM~! HERE

    exDao is null here, NullPointException occurs here. It's not correctly wired. Why?? And What should I do??

    My exampleDao

    public interface exampleDao {
        public List<HashMap<String, Object>> sampleList();
    }
    

    **My exampleDaoImplement

    public class exampleDaoImplement extends SqlSessionDaoSupport implements exampleDao {
    
        private static final Logger logger = LoggerFactory.getLogger(exampleDaoImplement.class);    
    
        public List<HashMap<String, Object>> sampleList() {
            // TODO Auto-generated method stub
    
            logger.info("I've reached impl class....");
            return getSqlSession().selectList("Example.selectTest");
    
        }
    }
    

    MY ROOT CONTEXT

    ( Forget about ****** anyway... )

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- Root Context: defines shared resources visible to all other web components -->
    
        <bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://*******:3306/*****_web"/>
            <property name="username" value="root"/>
            <property name="password" value="*******"/>
        </bean>
    
        <bean id ="sqlSessionFactory" class= "org.mybatis.spring.SqlSessionFactoryBean" >
            <property name ="dataSource" ref= "dataSource"></property >
            <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
        </bean >
    
        <bean id ="transactionManager"
            class= "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
            <property name ="dataSource" ref= "dataSource"></property >
        </bean >
    
        <bean id ="sqlSession"
            class= "org.mybatis.spring.SqlSessionTemplate" >
            <constructor-arg ref= "sqlSessionFactory"></constructor-arg >
        </bean >
    
        <bean id ="exService" class= "com.*****.web.service.exampleService" ></bean >
    
    </beans>
    

    My servlet-context

        <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:beans="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
            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">
    
        <!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
    
        <!-- Enables the Spring MVC @Controller programming model -->
        <annotation-driven />
    
        <!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
        <resources mapping="/resources/**" location="/resources/" />
    
        <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
        <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <beans:property name="prefix" value="/WEB-INF/views/" />
            <beans:property name="suffix" value=".jsp" />
        </beans:bean>
    
        <context:component-scan base-package="com.******.web.controller" />
    
    </beans:beans>
    

    I've googled on this for like a half a day, and got some hints but no exact solutions. What seems to be the matter??


    ADDED

    While googling, I got this hint and configured accordingly.

    <bean id ="exDao" class= "com.*****.web.dao.implement.exampleDaoImplement" >
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean >
    

    ( without defining property, It throws error while starting up the server, saying that property sqlSessionFactory or SqlSessionTemplate is required. )

    But it doesn't work... even with this configuration, there's still the nullpoint error.