newman555p
newman555p

Reputation: 181

spring - how to autowire data source?

I'm having some problem with autowire and DI in general, so I hope that someone can help cause I've been stuck for days now.

This is the code:

@Service
public class TicketsController implements Controller {
  private TicketManager ticketManager;

  @Autowired
public void setTicketManager(TicketManager ticketManager) {
    this.ticketManager = ticketManager;
}
...
}


@Service
public class SimpleTicketManager implements TicketManager {
  private TicketsDao ticketsDao;

@Autowired
public void setTicketsDao(TicketsDao ticketsDao) {
    this.ticketsDao = ticketsDao;
}
 ...
}

@Repository
public class JdbcTicketDao implements TicketsDao  {
  private DataSource dataSource;
  @Autowired
  public void setDataSource(DataSource dataSource)  {
    this.dataSource=dataSource;
      this.jdbcTemplate = new JdbcTemplate(this.dataSource);   
     }
...
}

public final class AppContext {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
BeanFactory factory = context;
TicketsController ticketsController = (TicketsController) factory.getBean("ticketsController");
}
...
}

In my beans.xml I've got:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mytckdb"/>
    <property name="username" value="user"/>
    <property name="password" value="pass"/>
</bean>
<context:component-scan base-package="bp.dao" />
<context:component-scan base-package="bp.mvc" />
<context:component-scan base-package="bp.svc" />
<context:component-scan base-package="bp.view" />

This doesn't work and I get:

Error creating bean with name 'jdbcTicketDao': Injection of autowired dependencies failed
... nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
    No matching bean of type [javax.sql.DataSource] found for dependency.` 

Can someone please help out with this? What am I doing wrong? It seems that autowiring is working all until the next step where it fails when injecting dataSource.

EDIT: I was playing with the code, and forgot @Autowire before setDataSource() but it is supposed to be there.

Upvotes: 3

Views: 17812

Answers (5)

venkat
venkat

Reputation: 11

This will be due to the order of bean instance creation. Your DAO has been instantiated before the dataSource instance created.

Keep your data Source bean definition before

other way is , define your dataSource definitions in a separate xml and import that before

Upvotes: 1

pap
pap

Reputation: 27614

Change

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mytckdb"/>
    <property name="username" value="user"/>
    <property name="password" value="pass"/>
</bean>

to

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/mytckdb"/>
    <property name="username" value="user"/>
    <property name="password" value="pass"/>
</bean>

The property is called driverClassName, not driverClass.

Also, you don't need multiple context:component-scan elements You can change

<context:component-scan base-package="bp.dao" />
<context:component-scan base-package="bp.mvc" />
<context:component-scan base-package="bp.svc" />
<context:component-scan base-package="bp.view" />

To

<context:component-scan base-package="bp.dao,bp.mvc,bp.svc,bp.view" />

Upvotes: 0

quartzde
quartzde

Reputation: 638

Looks like you are using Spring 2.0 but i think context:component-scan was introduced in Spring 2.5. Maybe update spring xml-config and spring dependencies to 2.5?

Upvotes: 0

Rrr
Rrr

Reputation: 1777

Maybe you're missing wiring configuration, try

<context:annotation-config/>

Upvotes: 2

Anshu
Anshu

Reputation: 7853

Try org.apache.commons.dbcp.BasicDataSource :

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver"
        p:url="jdbc:mysql://127.0.0.1:3306/mytckdb?autoReconnect=true"
        p:username="user" p:password="pass" />

I use JPA so generally prefer to create EntityManagerFactory and use that

    <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="persistenceUnitName" value="PU" />
            <property name="jpaVendorAdapter">
                <bean id="jpaAdapter"
                    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="database" value="${database}" />
                    <property name="showSql" value="true" />
                    <property name="generateDdl" value="false" />
                </bean>
            </property>
        </bean>

<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>

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

Upvotes: 0

Related Questions