Spring loading error when using AbstractRoutingDataSource and trying to configure multiple DataSources

I'm new to Spring's download, and I'm working on a new application that should be able to connect to one of several available databases. Based on user credentials, I determine which database to connect to, so I need the ability to dynamically change connections at runtime. I found an old Spring blog that describes a solution for here that protects the use of AbstractRoutingDataSource, which routes getConnection () calls to other DataSources based on search keys. I tried to keep a close eye on blogs, but I keep getting the following error.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in robb.referencecomponent.Application: Invocation of init method failed; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name 'dev1DataSource'; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial 

And here is the code for my Application.java class:

 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean @ConfigurationProperties(prefix="app.dev1.datasource") public DataSource dev1DataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix="app.dev2.datasource") public DataSource dev2DataSource() { return DataSourceBuilder.create().build(); } @Bean public DataSource dataSource() { return new RoutingDataSource(); } public class RoutingDataSource extends AbstractRoutingDataSource { public RoutingDataSource() { super(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DbLocation.DEV1, "dev1DataSource"); targetDataSources.put(DbLocation.DEV2, "dev2DataSource"); setTargetDataSources(targetDataSources); setDefaultTargetDataSource(DbLocation.DEV2); } @Override protected Object determineCurrentLookupKey() { return ClientContextHolder.getDbLocation(); } } } 

And I set the DataSource configuration in the properties file as follows:

 app.dev1.datasource.url=jdbc:oracle:thin:@dev1_db_url app.dev1.datasource.username=dev1 app.dev1.datasource.password=XXXXXXX app.dev1.datasource.driver-class-name=oracle.jdbc.OracleDriver app.dev2.datasource.url=jdbc:oracle:thin:@dev2_db_url app.dev2.datasource.username=dev2 app.dev2.datasource.password=XXXXXXX app.dev2.datasource.driver-class-name=oracle.jdbc.OracleDriver 

I called one of my dev1DataSource DataSources' and he complains that he cannot find it using JNDI, but when I remove the class RoutingDataSource and define dataSource () bean and make dev1DataSource () bean @Primary I can connect to the dev1 database . I'm not sure what I did wrong by porting this old blog code to my application, I know that beans were configured in the examples using xml, but mine were configured with Java code and annotations, maybe some errors were made in this translation?

Does anyone have any experience with AbstractRoutingDataSource in Spring boot and have they encountered such problems?

+5
source share
1 answer

AbstractRoutingDataSource supports several search engines. The value targetDataSources may vary depending on the DataSourceLookup , which is used by default to search for JNDI. This is why you see the initialization of NoInitialContextException .

You have two options for solving the problem:

  • Provide permitted instances of the DataSource instead of the lines dev1DataSource / dev2DataSource . You define two DataSource @Bean , and you pass DataSources to initialize your RoutingDataSource .
  • Create your own DataSourceLookup that displays configuration properties from Environment . Own DataSourceLookup will have to take care of caching the created instances and terminating the application, so I would recommend option 1.
+3
source

Source: https://habr.com/ru/post/1266985/


All Articles