0

web.xml

     <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>
               org.springframework.web.servlet.DispatcherServlet
           </servlet-class>
        <load-on-startup>1</load-on-startup>
      </servlet>

my spring-mvc-servlet.xml

     <context:component-scan base-package="org.app.controller" />   
        <mvc:resources mapping="/resources/**" location="/WEB-INF/resources/" />
        <mvc:annotation-driven />
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix">
                <value>/WEB-INF/pages/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>

my controller: Just for illustration

        @Controller
    public class HomeController {
        LoginService loginService;
        @RequestMapping(value = "/", method = RequestMethod.GET)
        public String login(Model model) {
            loginService.checkLoginDetails(new LoginDetails("Svn", 1));
            return "login";
        }

AppplicationContext.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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--    <context:annotation-config /> -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value=""></property>
    </bean>
    <bean class="org.app.controller.HomeController" autowire="byName"></bean>
    <bean id="loginDAO" class="org.app.DAOImpl.LoginDAOImpl" autowire="byName"></bean>
    <bean id="loginService" class="org.app.DAOServiceImpl.LoginServiceImpl" autowire="byName"></bean>
    <bean id="employeeDAO" class="org.app.DAOImpl.EmployeeDAOImpl" autowire="byName"></bean>
    <bean id="employeeService" class="org.app.DAOServiceImpl.EmployeeDAOServiceImpl" autowire="byName"></bean>
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="annotatedClasses">
            <list>
                <value>org.app.entity.Employee</value>
                <value>org.app.entity.LoginDetails</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>
    <!-- <context:component-scan base-package="org.infy"> <context:exclude-filter 
        expression="org.springframework.stereotype.Controller" type="annotation" 
        /> </context:component-scan> -->
    <tx:annotation-driven />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>

LoginServiceImpl

public class LoginServiceImpl implements LoginService{

    LoginDAO loginDAO;
    @Override
    @Transactional
    public boolean checkLoginDetails(LoginDetails loginDetails) {
        return loginDAO.checkLoginDetails(loginDetails);
    }

}

Problem: My LoginDAO is null. Spring is not able to instantiate it's object using auto-wiring when done without annotation, however, works fine when I use it with annotation along with appropriate changes in ApplicationContext.xml.

My LoginService bean is getting instantiated by the component scan of dispatcher servlet context. Now when instantiating LoginServiceImpl spring should look into RootApplication context for other bean definitions however it doesn't. I don't understand why does this happen when using @autowire with or enabling the component scan. it works fine then why not without annotation.

I'm also not sure what I'm trying to do. I was playing with Spring MVC and got stuck on this.

Kid101
  • 1,440
  • 11
  • 25

2 Answers2

0

In AppplicationContext.xml you need to specify injected dependencies for your beans as element inside

Stan
  • 1,410
  • 10
  • 14
  • what do you suggest @stan?. A little example would help me for sure. – Kid101 Jun 02 '16 at 12:09
  • I would definitely suggest to use annotations :) Remove all these XML definitions, annotate beans with Service and Repository annotations and go with Autowire – Stan Jun 02 '16 at 12:14
  • well, whenever I'm to use this. I'll surely use annotations, without a doubt but because I'm in my learning phase of Spring and Spring MVC. I'd appreciate if you or anyone can tell me on my mistakes. – Kid101 Jun 02 '16 at 12:19
  • I see. Then I would say Spring is not uses your config file since it's not default named and not specified in definition of dispatcher servlet. Please check default naming for spring config files in spring MVC or how to set it in servlet definition – Stan Jun 02 '16 at 12:26
  • the default name is always *servlet name*-servlet.xml and for root applicationContext it is always ApplicationContext.xml Even though I've not specified the location it will look for files under WEB-INF folder. BTW the files are getting loaded as I'm using hibernate and it drops and creates the table first. else it would've given an error for session Facory itself. – Kid101 Jun 02 '16 at 12:31
0

Please update your ApplicationContext.xml

<bean id="loginService" class="org.app.DAOServiceImpl.LoginServiceImpl" autowire="byName">
   <property name="loginDAO" ref="loginDAO"> </property>
</bean>

Same thing goes for the EmployeeService and your controller as well.

<bean class="org.app.controller.HomeController" autowire="byName">
    <property name="loginService" ref="loginService"> </property>
</bean>
<bean id="employeeService"  class="org.app.DAOServiceImpl.EmployeeDAOServiceImpl" autowire="byName">
    <property name="employeeDAO" ref="employeeDAO"> </property>
</bean>

Though I still recommend you to use annotations.

erolkaya84
  • 1,769
  • 21
  • 28
  • Yes, @erolkaya84. It works this way, using annotations. However, I just want to know why it doesn't work without annotations. – Kid101 Jun 02 '16 at 12:16
  • did you define loginDao as a property under your loginServiceImpl? If you didn't, then you should tag loginDao with @Autowire. – erolkaya84 Jun 02 '16 at 12:18
  • let's just call me old school. I don't want to use annotations and do it the XML way. It works with @Autowire sir. – Kid101 Jun 02 '16 at 12:22
  • no no what I want to say is if you are not using @Autowire, then you should do some configuration in your appContext.xml. Can you share your entire appContext.xml ? No need. I found the issue. I will update my answer – erolkaya84 Jun 02 '16 at 12:25
  • Doesn't work org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginService' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'loginDAO' of bean class [org.app.DAOServiceImpl.LoginServiceImpl]: Bean property 'loginDAO' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter? My field names are same. – Kid101 Jun 02 '16 at 12:46
  • Can you please share your LoginServiceImpl? – erolkaya84 Jun 02 '16 at 12:48
  • It is there in the question. – Kid101 Jun 02 '16 at 12:49
  • you don't have a setter for your property (loginDAO). Please create getter & setter of it, so Spring will use it to inject your property as a dependency to your service. – erolkaya84 Jun 02 '16 at 12:53
  • Thank you! I had to put setter and getter in every class for auto-wiring to work. I still have 2 doubts 1) when I'm creating the Homecontroller Bean in Application Context won't there be two beans residing in the whole context one in webApplcation context of the servlet(because of component-scan) and other in RootApplication Context(because we put it in there). 2)When use annotation for Autowiring does Reflection take care of setting? I think so. BTW thank you very much. – Kid101 Jun 02 '16 at 13:04
  • you're welcome. I believe this answer would clear your doubts http://stackoverflow.com/questions/3153546/how-does-autowiring-work-in-spring – erolkaya84 Jun 02 '16 at 13:12