Could not autowire field in spring. why?
Asked Answered
S

8

28

I keep getting this error, and can't figure out why.. yes I know there many people had similar issues, but reading the answers they got, does not solve my problem.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contactController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private net.service.ContactService net.controller.ContactController.contactService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [net.service.ContactService] 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)}

here is the controller:

@Controller
@SessionAttributes
public class ContactController {

    @Autowired
    private ContactService contactService;
//methods...


}

the ContactServiceImpl

@Service("contactService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ContactServiceImpl implements ContactService {

    @Autowired
    private ContactDao contactDao;

    public ContactServiceImpl() {
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
    public void addContact(Contact contact) {
        contactDao.saveContact(contact);
    }

    @Override
    public List<Contact> getContacts() {
        return contactDao.getAllContacts();
    }

}

the ContactDaoImpl

@Repository("contactDao")
public class ContactDaoImpl implements ContactDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void saveContact(Contact contact) {
        sessionFactory.getCurrentSession().saveOrUpdate(contact);
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Contact> getAllContacts() {
        return (List<Contact>) sessionFactory.getCurrentSession().createQuery("from contact c").list();
    }

}

and the spring-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:context="http://www.springframework.org/schema/context"
    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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <context:property-placeholder location="classpath:jdbc.properties" />
    <context:component-scan base-package="net.controller" />


    <tx:annotation-driven transaction-manager="hibernateTransactionManager" />

    <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="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${database.driver}" />
        <property name="url" value="${database.url}" />
        <property name="username" value="${database.user}" />
        <property name="password" value="${database.password}" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>net.form.Contact</value>
            </list>
        </property>


        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
            </props>
        </property>
    </bean>

    <bean id="hibernateTransactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
</beans>
Saponify answered 14/8, 2012 at 14:25 Comment(6)
so do you have setter method for contactService field?Bergwall
@Bergwall you don't need a setter method for that field in order for Spring injection to work. At any rate, the problem here is clearly the fact that the bean to inject is not found as far as Spring knows, not that it's found but it is unable to inject it.Etruscan
@DaveNewton: doh, you're right, I wrote a fancy long answer that doesn't mention that at all. Yes, if the package containing ContactServiceImpl is not amongs those declared as annotation-scannable, the bean will not be created and hence not be available for injection in other beansEtruscan
<context:component-scan base-package="net" /> solved the problem as Pyranja suggested belowHuckaby
@pr123 And as I suggested in my comment prior to that.Period
@Dave yes, sorry but I read the answers prior to the commentsHuckaby
S
35

In spring servlet .xml :

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

(I assumed that the service impl is in the same package as the service interface "net.service")

I think you have to add the package net.service (or all of net) to the component scan. Currently spring only searches in net.controller for components and as your service impl is in net.service, it will not be instantiated by spring.

Savarin answered 14/8, 2012 at 14:35 Comment(2)
yes, that was a great idea. <context:component-scan base-package="net" />Huckaby
I have mistakenly keept the serivice into some other package, It worked great. thanks.Menstrual
T
12

I was getting this same error and searching for it led me here. My fix appeared to be simply to add @Component annotation to the implementation of the abstract service.

In this case, that would look like:

import org.springframework.stereotype.Component;

...

@Component
public class ContactServiceImpl implements ContactService {
Twitt answered 9/9, 2013 at 18:11 Comment(0)
E
9

Well there's a problem with the creation of the ContactServiceImpl bean. First, make sure that the class is actually instantiated by debugging the no-args constructor when the Spring context is initiated and when an instance of ContactController is created.

If the ContactServiceImpl is actually instantiated by the Spring context, but it's simply not matched against your @Autowire annotation, try being more explicit in your annotation injection. Here's a guy dealing with a similar problem as yours and giving some possible solutions:

http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/

If you ask me, I think you'll be ok if you replace

@Autowired
private ContactService contactService;

with:

@Resource
@Qualifier("contactService")
private ContactService contactService;
Etruscan answered 14/8, 2012 at 14:33 Comment(0)
C
6

When you get this error some annotation is missing. I was missing @service annotation on service. When I added that annotation it worked fine for me.

Chive answered 27/5, 2015 at 19:5 Comment(0)
P
1

I've faced the same issue today. Turned out to be I forgot to mention @Service/@Component annotation for my service implementation file, for which spring is not able autowire and failing to create the bean.

Prepossession answered 8/3, 2017 at 13:39 Comment(0)
M
0

I had exactly the same problem try to put the two classes in the same package and add line in the pom.xml

<dependency> 
            <groupId> org.springframework.boot </groupId> 
            <artifactId> spring-boot-starter-web </artifactId> 
            <version> 1.2.0.RELEASE </version> 
</dependency>
Maniac answered 30/4, 2015 at 13:32 Comment(0)
D
0

In java config,make sure you have import your config in RootConfig like this @Import(PersistenceJPAConfig.class)

Disconnect answered 13/3, 2016 at 13:8 Comment(0)
M
0

Encountered similar error, and tried the solutions earlier mentioned in this post but none of them worked for me. What finally resolved the issue was to set @Autowired(required = false)

Megmega answered 20/3, 2022 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.