Hi all,

I am having a problem with eager bean creation. Lets assume we have the following @Configuration class:

Code:
@Configuration
@Profile("development")
@PropertySource("classpath:dev.properties")
public class DevelopmentRepositoryConfig {
	
	@Autowired
	@Qualifier("wurthshopDataSource")
	private DataSource shopDataSource;
//more datasources - not needed for demonstration
	@Autowired
	Environment env;
	
	@Bean(autowire = Autowire.BY_NAME)
	public ComboPooledDataSource shopDataSource() throws PropertyVetoException {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setUser(env.getProperty("db.user"));
		dataSource.setPassword(env.getProperty("db.password"));
		dataSource.setJdbcUrl(env.getProperty("db.url"));
		dataSource.setDriverClass(env.getProperty("db.driverClass.mysql"));
		dataSource.setIdleConnectionTestPeriod(600);
		dataSource.setPreferredTestQuery("SELECT 1;");
		dataSource.setMinPoolSize(5);
		dataSource.setMaxPoolSize(10);
		dataSource.setMaxIdleTime(60);
		return dataSource;
	}
	
	@Bean(autowire = Autowire.BY_NAME)
	public SessionFactory wurthshopSessionFactory(){
		Properties props = new Properties();
		props.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
		props.setProperty("hibernate.current_session_context_class", "org.springframework.orm.hibernate4.SpringSessionContext");
		props.setProperty("hibernate.connection.driver_class", env.getProperty("db.driverClass.mysql"));
		props.setProperty("hibernate.connection.url", env.getProperty("db.url"));
		props.setProperty("hibernate.connection.username", env.getProperty("db.user"));
		props.setProperty("hibernate.connection.password", env.getProperty("db.password"));
		props.setProperty("hibernate.c3p0.min_size", "10");
		props.setProperty("hibernate.c3p0.max_size", "50");
		//props.setProperty("hibernate.c3p0.timeout", "1800");
		props.setProperty("hibernate.c3p0.max_statements", "50");
		props.setProperty("hibernate.c3p0.preferredTestQuery", "SELECT 1;");
		props.setProperty("hibernate.c3p0.idle_test_period", "600");
		props.setProperty("hibernate.c3p0.validate", "true");
		props.setProperty("hibernate.c3p0.timeout", "300");
		return new LocalSessionFactoryBuilder(shopDataSource)
			.scanPackages("com.shop.domain")
			.setProperties(props)
			.buildSessionFactory();
	}

//more datasources and sessionFactories - not needed for demonstration

}
Testing this with the following throws an error - everything works fine when not using @PropertySource for DataSource properties and env.getProperty():

Code:
@ContextConfiguration(classes= {PropertiesConfig.class, DevelopmentRepositoryConfig.class}, loader = AnnotationConfigContextLoader.class)
@ActiveProfiles("development")
public class HibernateConfigurationTest extends AbstractJUnit4SpringContextTests {

	@Autowired
	@Qualifier("shopSessionFactory")
	private SessionFactory sessionFactory;
	@Autowired
	Environment env;

	@Test
	public void testEnvironment() {
		assertTrue("environment is dev", "development".equals(env.getActiveProfiles()[0]));
		assertTrue("shop user is root", "root".equals(env.getProperty("db.user")));
		assertTrue("shop password is root", "root".equals(env.getProperty("db.password")));
		
		assertTrue("shop url is", "jdbc:mysql://localhost/shop".equals(env.getProperty("db.url")));
		assertTrue("shop driver is", "com.mysql.jdbc.Driver".equals(env.getProperty("db.driverClass.mysql")));
	}
	
	@Test
	public void testHibernateConfiguration() {
		// Spring IOC container instantiated and prepared sessionFactory
		assertNotNull(sessionFactory);
	}

}
I will end up with java.lang.IllegalStateException: Failed to load ApplicationContext and the following log:

Code:
14:09:10,119 DEBUG DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'developmentRepositoryConfig'
14:09:10,120 DEBUG DefaultListableBeanFactory:430 - Creating instance of bean 'developmentRepositoryConfig'
14:09:10,122 DEBUG InjectionMetadata:60 - Found injected element on class [com.wurthusa.intranet.config.DevelopmentRepositoryConfig$$EnhancerByCGLIB$$6a31034a]: AutowiredFieldElement for private javax.sql.DataSource com.shop.config.DevelopmentRepositoryConfig.shopDataSource
14:09:10,123 DEBUG InjectionMetadata:60 - Found injected element on class [com.shop.config.DevelopmentRepositoryConfig$$EnhancerByCGLIB$$6a31034a]: AutowiredFieldElement for private javax.sql.DataSource com.shop.config.DevelopmentRepositoryConfig.specialOrdersDataSource
14:09:10,123 DEBUG InjectionMetadata:60 - Found injected element on class [com.shop.config.DevelopmentRepositoryConfig$$EnhancerByCGLIB$$6a31034a]: AutowiredFieldElement for private javax.sql.DataSource com.shop.config.DevelopmentRepositoryConfig.vacationDataSource
14:09:10,123 DEBUG InjectionMetadata:60 - Found injected element on class [com.shop.config.DevelopmentRepositoryConfig$$EnhancerByCGLIB$$6a31034a]: AutowiredFieldElement for org.springframework.core.env.Environment com.shop.config.DevelopmentRepositoryConfig.env
14:09:10,123 DEBUG DefaultListableBeanFactory:504 - Eagerly caching bean 'developmentRepositoryConfig' to allow for resolving potential circular references
14:09:10,126 DEBUG InjectionMetadata:85 - Processing injected method of bean 'developmentRepositoryConfig': AutowiredFieldElement for private javax.sql.DataSource com.shop.config.DevelopmentRepositoryConfig.shopDataSource
14:09:10,127 DEBUG DefaultListableBeanFactory:217 - Creating shared instance of singleton bean 'shopDataSource'
14:09:10,127 DEBUG DefaultListableBeanFactory:430 - Creating instance of bean 'shopDataSource'
14:09:10,127 DEBUG DefaultListableBeanFactory:241 - Returning eagerly cached instance of singleton bean 'developmentRepositoryConfig' that is not fully initialized yet - a consequence of a circular reference
Could it be that @PropertySource is initialized too late to actually be used within the DevelopmentRepositoryConfig? Both tests will fail when using @PropertySource properties in DataSource/SessionFactory bean but pass when db.user etc. are set directly - meaning Environment itself seems to be fine.

Any input is appreciated,
Michael

dev.properties:
Code:
db.driverClass.mysql=com.mysql.jdbc.Driver
db.user.shop=root
db.password.shop=root
db.url.shop=jdbc\:mysql\://localhost/shop