2
votes

Just a few weeks into Spring I'm stuck with NoSuchBeanDefinitionException. Tried to find a solution reading other questions here on SO but have no luck. I'm getting this error when trying to launch my simple Spring application in Eclipse:

aug 29, 2015 7:33:45 PM org.springframework.context.support.ClassPathXmlApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'offersDao': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void by.blabla.spring.test.OffersDAO.setDataSource(javax.sql.DataSource); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

I have only one dependency injection in OffersDAO.java using @Autowired annotation. BasicDataSource bean which implements DataSource interface is defined in beans.xml configuration file but my app somehow couldn't wire to it.

Configuration file beans.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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

    <context:annotation-config></context:annotation-config>

    <context:component-scan base-package="by.blabla.spring.test"></context:component-scan>

    <context:property-placeholder location="by/blabla/spring/props/jdbc.properties" />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="username" value="${jdbc.username}"></property>
    </bean>

</beans>

Main application file App.java:

package by.blabla.spring.test;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("by/blabla/spring/test/beans/beans.xml");

        OffersDAO offersDao = (OffersDAO)context.getBean("offersDao");

        List<Offer> list = offersDao.getOffers();

        for(Offer offer : list){
            System.out.println(offer);
        }

        ((ClassPathXmlApplicationContext)context).close();
    }
}

OffersDAO.java:

package by.blabla.spring.test;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

@Component("offersDao")
public class OffersDAO {

    private JdbcTemplate jdbc;

    @Autowired
    public void setDataSource(DataSource jdbc) {
        this.jdbc = new JdbcTemplate(jdbc);
    }

    public List<Offer> getOffers() {

        return jdbc.query("select * from offers", new RowMapper<Offer>() {

            public Offer mapRow(ResultSet rs, int rowNum) throws SQLException {
                Offer offer = new Offer();
                offer.setId(rs.getInt("id"));
                offer.setName(rs.getString("name"));
                offer.setEmail(rs.getString("email"));
                offer.setText(rs.getString("text"));

                return offer;
            }
        });
    }
}
2
Unsuccessfully tried to explicitly pointing to the bean with @Resource(name="dataSource")tdrive
Could u plz provide the full stack trace (the whole log , start to end) & the version of Spring?Bacteria
Spring version is 4.1.7. Please find the log here: hastebin.com/rapuruloni.valatdrive

2 Answers

0
votes

In your dao class , ter is no property declared with type DataSource. IOC trying to listout properties to be injected using Reflection but it finds no parameter with the name and type mentioned in the bean configuration file

Your code should be as follows

@Component("offersDao") 
public class OffersDAO {
 private JdbcTemplate jdbc;
 private DataSource datasource;
  @Autowired public void setDataSource(DataSource ds) { 
this.datasource=ds;
this.jdbc = new JdbcTemplate(ds); 
} 

Suggestion: It is better to create ur jdbc template in spring context and inject it rather than injecting datasource and creating template object ...

0
votes

Try this:

@Component("offersDao")
public class OffersDao implements InitializingBean {

private JdbcTemplate jdbc;

@Autowired
private DataSource dataSource;

@Override
public void afterPropertiesSet() throws Exception {
    this.jdbc = new JdbcTemplate(this.dataSource);
}

public List<Offer> getOffers() {

    return jdbc.query("select * from offers", new RowMapper<Offer>() {

        public Offer mapRow(ResultSet rs, int rowNum) throws SQLException {
            Offer offer = new Offer();
            offer.setId(rs.getInt("id"));
            offer.setName(rs.getString("name"));
            offer.setEmail(rs.getString("email"));
            offer.setText(rs.getString("text"));

            return offer;
        }
    });
}
}