Reputation: 353
So one of my configuration classes includes both (Testing/Production)DatabaseConfig classes, and the right one gets chosen by the the active profile. But when the DatabaseConfig class runs, it's dataSource ivar is null.
I did a debug, my TestingDatabaseConfig's dataSource() method is run before DatabaseConfig's localContainerEntityManagerFactoryBean() is run.
I guess my question is, why isn't this working, should it work, and what am I doing wrong?
@Configuration
@Profile({"testing-db", "production-db"})
@Import({TestingDatabaseConfig.class, ProductionDatabaseConfig.class})
@EnableTransactionManagement
public class DatabaseConfig
{
@Resource
private DataSource dataSource;
@Bean(name = "entityManager")
public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean()
{
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(this.dataSource);
// other config
return entityManagerFactoryBean;
}
// ... other db related beans stuff ...
}
@Configuration
@Profile("testing-db")
public class TestingDatabaseConfig implements DatabaseConfigInterface
{
@Bean(name="dataSource")
public DataSource dataSource()
{
JDBCDataSource dataSource = new JDBCDataSource();
dataSource.setDatabase("jdbc:hsqldb:mem:testing");
dataSource.setUser("sa");
return dataSource;
}
}
Upvotes: 1
Views: 6384
Reputation: 353
It seems that things do not just magically work! If you want configuration classes to have their ivars autowired, you have to have it configured correctly, or in this case, having another bean that does the autowiring.
You need to create the AutowiredAnnotationBeanPostProcessor bean.
@Bean
public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor()
{
return new AutowiredAnnotationBeanPostProcessor();
}
or
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
Upvotes: 0
Reputation: 353
Ok, so I must have just done this wrong the first time, but the solution is to let the beans be autowired as parameters instead of trying to have them injected as an ivar. A fake diff of what I had to change to get it to work…
- @Resource
- private DataSource dataSource;
- public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean()
+ public LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean(DataSource dataSource)
- entityManagerFactoryBean.setDataSource(this.dataSource);
+ entityManagerFactoryBean.setDataSource(dataSource);
Ended up being cleaner than what I was trying to do anyways =)
Upvotes: 0
Reputation: 3903
Of course they're not injected before the call to the constructor.
Use @PostConstruct. Here's a nice example: http://www.mkyong.com/spring/spring-postconstruct-and-predestroy-example/
Upvotes: 2