Skip to content

Application fails to start with 3.2.0-RC1 when configuring multiple datasources and dialects #1650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kota65535 opened this issue Oct 25, 2023 · 6 comments
Assignees
Labels
status: superseded An issue that has been superseded by another

Comments

@kota65535
Copy link

kota65535 commented Oct 25, 2023

In this repository, I've finally managed to configure repositories with multiple datasources and dialects (MySQL, PostgreSQL, Microsoft SQL Server), which goes like this:

  • Create necessary beans with @Qualifier for each datasource
  • Create a repository factory class inheriting JdbcRepositoryFactoryBean that injects the @Qualifier-ed beans for each datasource
  • Use the repository factory class by specifying repositoryFactoryBeanClass of @EnableJdbcRepositories for each datasource

But Bumping from 3.1.5 to 3.2.0-RC1, the application does not start by the following exception.

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.jdbc.core.mapping.JdbcMappingContext' available: expected single matching bean but found 3: jdbcMappingContextDb1,jdbcMappingContextDb2,jdbcMappingContextDb3

I've defined 3 JdbcMappingContext beans for each datasource, but the application looks to assume a single JdbcMappingContext bean. It is likely due to this commit that changed the behavior.

Adding @Primary to beans for a specific datasource will launch the application, but it results in using the wrong beans for repositories for another datasource.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Oct 25, 2023
@kota65535 kota65535 changed the title Application fails to start with 3.2.0-RC1 when configuring multiple repositories and dialects Application fails to start with 3.2.0-RC1 when configuring multiple datasources and dialects Oct 25, 2023
@mp911de
Copy link
Member

mp911de commented Oct 25, 2023

Sorry for inconvenience. This falls back on us as our current configuration model picks individual components from the application context instead of referring to a single component that could provide the dialect, mapping context and converter.

With all that hassle, I suggest moving off @EnableJdbcRepositories for the time being until we have solved the configuration issue. Instead, you can register your own repository instances by using JdbcRepositoryFactory.

@kota65535
Copy link
Author

@mp911de

With all that hassle, I suggest moving off @EnableJdbcRepositories for the time being until we have solved the configuration issue. Instead, you can register your own repository instances by using JdbcRepositoryFactory.

Do you have any examples?

Rather than that, is there any possibility of reverting this commit for now?
According to the linked issue #1143, the commit enables us to use different JdbcMappingContext beans for JDBC and R2DBC repositories. But actually, it looks to force us to use a single JdbcMappingContext bean as I experienced.

@mp911de
Copy link
Member

mp911de commented Oct 26, 2023

The commit that changed behavior fixes a bug for users that want to use JDBC and R2DBC within a single application.

Using a single JdbcMappingContext should generally work fine unless you want to have specific SimpleTypeHolder or NamingStrategy configurations that you do not want to share across mapping context instances.

What is the reason that you want to use different JdbcMappingContext instances?

A sample to use JdbcRepositoryFactor from your code would look like:

@Configuration
public class MyConfig {
	
	private final JdbcRepositoryFactory factory1;
	private final JdbcRepositoryFactory factory2;

	public MyConfig(…) {
		this.factory1 = new JdbcRepositoryFactory(…);
		this.factory2 = new JdbcRepositoryFactory(…);
	}
	
	@Bean
	public MyRepository1 myRepository1() {
		return factory1.getRepository(MyRepository1.class);
	}
	
	@Bean
	public MyRepository2 myRepository2() {
		return factory2.getRepository(MyRepository2.class);
	} 
}

@kota65535
Copy link
Author

kota65535 commented Oct 27, 2023

Thank you for the example. I didn't know repository beans could be defined in such a way. But It is a little cumbersome to create each repository bean by hand...

Using a single JdbcMappingContext should generally work fine unless you want to have specific SimpleTypeHolder or NamingStrategy configurations that you do not want to share across mapping context instances.

Oh, I didn't know it is OK to share JdbcMappingContext if we have the same SimpleTypeHolder and NamingStrategy.
But what is more important is that Dialect and JdbcConverter are also forced to be a single bean, which should be different instances for each datasource if we use different RDBMSs.

@mp911de
Copy link
Member

mp911de commented Oct 27, 2023

Yeah, you're totally right with Dialect and the converter. I'm happy that you found a workaround until we fix #687. I suggest closing this ticket as duplicate. What do you think?

@mp911de mp911de self-assigned this Oct 27, 2023
@kota65535
Copy link
Author

kota65535 commented Oct 27, 2023

In 3.1.x, we can already configure multiple repositories with different dialects as I have shown here, so I'm afraid that people including me customizing repositories this way will suffer this regression when updating to 3.2.0.

#687 is an enhancement to make it configurable more easily (In fact, I'm working on it now ;)

@mp911de mp911de added status: superseded An issue that has been superseded by another and removed status: waiting-for-triage An issue we've not yet triaged labels Nov 10, 2023
@mp911de mp911de closed this as not planned Won't fix, can't repro, duplicate, stale Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded An issue that has been superseded by another
Projects
None yet
Development

No branches or pull requests

3 participants