spring-boot: BeanCurrentlyInCreationException when two DataSources used with DataSourceInitializer

It appears that when there are two DataSource beans created and one bean factory method calls the other DataSource’s bean factory method (e.g. in a delegate pattern), DataSourceInitializer triggers a circular bean reference. It doesn’t help that one bean is tagged @Primary.

Apologies if I’m doing something incorrectly. I posted at Stack Overflow and did not get responses. I reviewed the doc and I believe I’ve followed that, and it does not mention this delegate pattern.

I’ve created a sample repository with two junit tests that demonstrate the issue. The full stack trace is also available there along with some analysis. In summary, the @Primary DataSource bean triggers creation of the subordinate DataSource bean which completes successfully. The creation of the subordinate bean triggers DataSourceInitializer which asks the bean factory for the DataSource and the bean factory selects the @Primary which is still in creation.

I’ve reviewed both open and closed issues and found several relevant issues: #2383 is similar but isn’t using @Primary, #8068 seems unrelated, #7652 mentions tricks needed for a similar setup but doesn’t have the same relationship between the two beans, #5541 implies this should work but again doesn’t have one factory bean calling the other factory bean, #5104 suggests using @Primary which doesn’t help in this case. #2784 seems to be the closest match and was closed per 9c733128ac942ac4675b27d2d358afa941fea5fd. However, 9c733128ac942ac4675b27d2d358afa941fea5fd only seems to update the Rabbit and JMS configuration. Should @ConditionalOnSingleCandidate also be used for the DataSourceInitializer?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 15 (5 by maintainers)

Most upvoted comments

@snicoll thanks, that was my analysis as well. I did find a workaround - by using @DependsOn("dataSourceInitializer") on the @Primary bean definition, spring eagerly creates the dataSourceInitializer bean before the primary is marked as in creation. Kind of a hack but works for now.

@AleksandarTokarev The easiest solution is to exclude DataSourceAutoConfiguration.class like the following: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

@rvit34 Can probably wrap the DataSource

class DSHolder {
    DataSource dataSource
}

ConfigurationProperties probably won’t work so have to do it old way.