Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not autowire field in spring. why?

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>
like image 577
Sanyifejű Avatar asked Aug 14 '12 14:08

Sanyifejű


People also ask

Why is Autowired not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

How do I turn on Autowire in spring?

In Spring, you can use @Autowired annotation to auto-wire bean on the setter method, constructor , or a field . Moreover, it can autowire the property in a particular bean. We must first enable the annotation using below configuration in the configuration file. We have enabled annotation injection.

What will happen if I make @autowired as false?

By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .

What is difference between @bean and @autowire?

@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).


5 Answers

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.

like image 161
Pyranja Avatar answered Sep 30 '22 01:09

Pyranja


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 {
like image 43
DKLEO Avatar answered Oct 03 '22 01:10

DKLEO


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.

like image 30
bond Avatar answered Oct 03 '22 01:10

bond


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;
like image 36
Shivan Dragon Avatar answered Oct 01 '22 01:10

Shivan Dragon


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.

like image 35
Sidd Thota Avatar answered Oct 03 '22 01:10

Sidd Thota