0
votes

I'm currently using Spring 3 annotations along with hibernate 3 for the database connectivity. I also have to be using spring tiles.
My spring-servlet.xml is:

    <context:annotation-config />
<context:component-scan base-package="com.xxx.controller,com.xxx.dao,com.xxx.service" />

<mvc:annotation-driven />

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
    id="viewResolver">
    <property name="viewClass">
        <value>
            org.springframework.web.servlet.view.tiles2.TilesView
        </value>
    </property>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
    id="tilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/plugin/impl/tiles/springtiles-defs.xml</value>
        </list>
    </property>
</bean>

//Is this required????
<!-- <bean id="MyDAO" class="com.xxxx.MyDAOImpl"></bean>
<bean id="MyService" class="com.xxxx.MyServiceImpl"></bean> -->

My controller class :

@Controller
public class myController {

    @Autowired
    private MyService myService;
    public myController() {

    }

    @RequestMapping(value="/index.do", method = RequestMethod.GET)
    protected ModelAndView Submit(HttpServletRequest request, HttpServletResponse response) throws Exception {

        // TODO Auto-generated method stubs
        System.out.println(" Inside the controller ");

</beans>

And my serviceImpl class:

    @Service("MyService")
public class MyServiceImpl implements MyService{

@Autowired
MyDAO myDAO;

And my DaoImpl class :

   @Repository/*("myDAO")*/
   public class MyDAOImpl implements MyDAO{

List<String> clientList;

 @Autowired
 private SessionFactory sessionFactory;

 private Session session;

 private Session currentSession() {
        return this.sessionFactory.getCurrentSession();
    }

@Override
public List<ClientInfoBean> getClientList(String currentQrt) throws DataStoreException {
    // TODO Auto-generated method stub
    return (List<ClientInfoBean>) this.currentSession().
    createCriteria("Select * from myTable);
}

It still gives the below exceptions.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.xxx.service.MyService com.xxx.controller.MyController.MyService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) ... 97 more

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) ... 99 more

5
Can you just make one parent package for that ?: <context:component-scan base-package="com.xxx" />Paweł Głowacz
Yes tried that as well. Still gives same error as pasted below. :(JaveDeveloper
your definitions of services and daos are in the same packages as implementation ?Paweł Głowacz
Impl are in a different package and the definitions are in a different package : com.service and com.serviceImplJaveDeveloper
com.serviceImpl or com.service.impl?Paweł Głowacz

5 Answers

1
votes

So the problem is your packages:

You have definition of services and daos in: com.xxx.service and com.xxx.dao

and your implementation in: com.xxx.serviceImpl and com.xxx.daoImpl.

Add in also <context:component-scan base-package="com.xxx.serviceImpl,com.xxx.daoImpl"/>

Next problem you are facing is transactional management:

You havent defined it in spring configuration. This is an example how to do this:

<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
<bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.jdbc.batch_size">${batchSize}</prop>
        </props>
    </property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

And after this you need to mark a method or your service implementation as @Transactional to make spring care of this.

1
votes

The exception is clearly telling you that the bean is not configured NoSuchBeanDefinitionException: No qualifying bean of type [com.xxx.service.MyService]

Can you check the case of the bean names that you given in annotations are matching with the parameter name. myService vs MyService.

Also adding a setter might be a good idea as spring can call setter to inject the dependency instead of using Reflection to inject it.

1
votes

When you define @Service("MyService") public class MyServiceImpl implements MyService{ } or @Repository("MyDAO") public class MyDAOImpl implements MyDAO{ } you are actually telling spring to create bean with the name "MyService" & "MyDAO"

when you define like @Autowired private MyService myService; @Autowired private MyDAO myDAO; you are asking from spring to give bean(s) with the name "myService" & "myDAO".

Since spring creates bean with the name which is different from what are you asking, it is giving the error. You have to keep name of the bean in the @Service & @Repository annotation same as the variable name for the Interface.

@Service("myService")
public class MyServiceImpl implements MyService{
}

private MyService myService;
1
votes

As you qualified your service as "MyService" , you can add qualifier as below to find it. By default spring should autowire by type , so component scan should load your service. If you are defining beans partially in xml and expecting other services to be autowired, you have to add in your spring-servlet.xml

@Autowired
  @Qualifier("MyService")
    private MyService myService;

Also change your controller class as MyController instead of myController. And remove the constructor myController(), spring will construct for you controller bean. Try to remove all your constructors in all your spring bean classes, spring will construct for you. For the beginning you can avoid qualifying the beans, remove the names in brackets( "MyService", "MyDao" etc....)

0
votes

Use

@Service
public class MyServiceImpl implements MyService

Instead of

@Service("MyService")
public class MyServiceImpl implements MyService{