Iain
Iain

Reputation: 29

@Autowired bean not being found

I'm getting errors trying to inject resource dependencies into my unit testing. My approach has been to write a TestConfig.java to replace the applicationContext.xml for production which manages the connections of the beans. So that I can run it with an in-memory database and just test components.

TestConfig.java

@Configuration
@EnableTransactionManagement
public class TestConfig {
@Bean
public DataSource dataSource() {
    DriverManagerDataSource ds = new DriverManagerDataSource();
    ds.setDriverClassName("org.hsqldb.jdbcDriver");
    ds.setUrl("jdbc:hsqldb:mem:testdb");
    ds.setUsername("sa");
    ds.setPassword("");
    return ds;

}

@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){

    LocalContainerEntityManagerFactoryBean lcemfb
        = new LocalContainerEntityManagerFactoryBean();

    lcemfb.setDataSource(this.dataSource());
    lcemfb.setPackagesToScan(new String[] {"com.dao","com.data"});
    lcemfb.setPersistenceUnitName("MyTestPU");

    HibernateJpaVendorAdapter va = new HibernateJpaVendorAdapter();
    lcemfb.setJpaVendorAdapter(va);

    Properties ps = new Properties();
    ps.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
    ps.put("hibernate.hbm2ddl.auto", "create");
    lcemfb.setJpaProperties(ps);

    lcemfb.afterPropertiesSet();

    return lcemfb;

}

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager tm = new JpaTransactionManager();
    tm.setEntityManagerFactory(this.entityManagerFactoryBean().getObject());

    return tm;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}

@Bean
public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor()
{
    return new AutowiredAnnotationBeanPostProcessor();
}


}

ProductsDaoTest.java

@ContextConfiguration(classes = { TestConfig.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class ProductsDaoTest {

 @Resource(name="com.dao.ProductsDao")
 private ProductsDao testDao;

 @Test
 public void testSaveProduct() {


     Product productA = new Product();
     testDao.save(productA);

     Set<Product> products = testDao.getAllProducts();

     assertNotNull(products);
 }   
}

The error is Error creating bean with name 'com.dao.ProductsDaoTest': Injection of resource dependencies failed

So it can't find the ProductDao Bean which is a @Repository with a @Autowired sessionFactory.

So my guess is that because I'm not naming the beans using xml it can't find it, though I thought it should automatically pick it up from setPackagesToScan(). So is there a way to manually insert the Bean mapping so that it can be found?

Also more generally is this a reasonable way to go about testing Spring DAO configurations?

Regards, Iain

Upvotes: 0

Views: 12631

Answers (1)

dimas
dimas

Reputation: 6073

I think you are trying to use wrong name of your DAO bean in @Resource annotation. Have you explicitly specify name of the ProductsDao bean using @Qualifier? If no, then as I remember by default the name of the bean will be productsDao. So you should inject your DAO like:

@Resource(name="productsDao")
private ProductsDao testDao;

If you have only one ProductDAO implementation then simply write:

@Autowired
private ProductsDao testDao;

or

@Inject
private ProductsDao testDao;

In case if you want to give specific name to DAO then use next construction:

@Respository
@Qualifier(name="specificName")
public class ProductDAO...

EDIT:

As Boris noted you should also specify which package to scan for defined beans (classes annotated with @Component, @Service, @Repository...). For this you should add @ComponentScan annotation to your configuration class definition.

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"package_to_scan"})
public class TestConfig {...}

Upvotes: 4

Related Questions