Configuring Mutiple DataSource in Spring Boot Using JNDI

I want to manage a mutiple DataSource using the built-in functions of your applications and accessing them using JNDI. I am using Spring boot with Spring JPA data.

I can configure application.properties for a single data source: -

spring.datasource.jndi-name=jdbc/customers 

And my configuration in context.xml as below: -

 <Resource name="jdbc/customer" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/customer"/> 

Everything is working fine.

But when I can not configure for two data sources.

I am sure of the configuration in the context.xml file: -

  <Resource name="jdbc/customer" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/customer"/> <Resource name="jdbc/employee" auth="Container" type="javax.sql.DataSource" maxTotal="100" maxIdle="30" maxWaitMillis="10000" username="root" password="root" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/employee"/> 

I doubt the configuration of the application.properties file.

I tried the following options without success: -

 spring.datasource.jndi-name=jdbc/customers,jdbc/employee 

Please let me know any details about loading Spring from JNDI to get multiple data sources. I have been looking for this configuration for several days now. Any suggestions or comments are greatly appreciated.

Spring Second Test Download Documentation

 spring.datasource.primary.jndi-name=jdbc/customer spring.datasource.secondary.jndi-name=jdbc/project 

Configuration class.

 @Bean @Primary @ConfigurationProperties(prefix="datasource.primary") public DataSource primaryDataSource() { return DataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix="datasource.secondary") public DataSource secondaryDataSource() { return DataSourceBuilder.create().build(); } 

The application does not start. Although the tomcat server is starting up. There are no errors in the log.

Third test: - using JndiObjectFactoryBean

I have the following application.properties

 spring.datasource.primary.expected-type=javax.sql.DataSource spring.datasource.primary.jndi-name=jdbc/customer spring.datasource.primary.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.datasource.primary.jpa.show-sql=false spring.datasource.primary.jpa.hibernate.ddl-auto=validate spring.datasource.secondary.jndi-name=jdbc/employee spring.datasource.secondary.expected-type=javax.sql.DataSource spring.datasource.secondary.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.datasource.secondary.jpa.show-sql=false spring.datasource.secondary.jpa.hibernate.ddl-auto=validate 

And the bottom java configuration: -

 @Bean(destroyMethod="") @Primary @ConfigurationProperties(prefix="spring.datasource.primary") public FactoryBean primaryDataSource() { return new JndiObjectFactoryBean(); } @Bean(destroyMethod="") @ConfigurationProperties(prefix="spring.datasource.secondary") public FactoryBean secondaryDataSource() { return new JndiObjectFactoryBean(); } 

But still a mistake: -

 Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'primaryDataSource' defined in class path resource [com/web/initializer/MvcConfig.class]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [jdbc/customer] is not bound in this Context. Unable to find [jdbc]. Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'secondaryDataSource' defined in class path resource [com/web/initializer/MvcConfig.class]: Invocation of init method failed; nested exception is javax.naming.NameNotFoundException: Name [jdbc/employee] is not bound in this Context. Unable to find [jdbc]. at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474) at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117) at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108) at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68) at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175) 

Update: - Trial use of the properties file below: -

  spring.datasource.primary.expected-type=javax.sql.DataSource spring.datasource.primary.jndi-name=java:comp/env/jdbc/customer spring.datasource.secondary.jndi-name=java:comp/env/jdbc/employee spring.datasource.secondary.expected-type=javax.sql.DataSource spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=validate 

It creates all the tables in the client schema, but does not try to find other tables. (from the second diagram)

+5
source share
3 answers

This solution for your third test is slightly modified. Consider this solution (Spring Boot 1.3.2):

file application.properties:

 spring.datasource.primary.jndi-name=java:/comp/env/jdbc/SecurityDS spring.datasource.primary.driver-class-name=org.postgresql.Driver spring.datasource.secondary.jndi-name=java:/comp/env/jdbc/TmsDS spring.datasource.secondary.driver-class-name=org.postgresql.Driver spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect spring.jpa.show-sql=false 

Configuration:

 @ Configuration@ EnableConfigurationProperties public class AppConfig { @ Bean@ ConfigurationProperties(prefix = "spring.datasource.primary") public JndiPropertyHolder primary() { return new JndiPropertyHolder(); } @ Bean@ Primary public DataSource primaryDataSource() { JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); DataSource dataSource = dataSourceLookup.getDataSource(primary().getJndiName()); return dataSource; } @ Bean@ ConfigurationProperties(prefix = "spring.datasource.secondary") public JndiPropertyHolder secondary() { return new JndiPropertyHolder(); } @Bean public DataSource secondaryDataSource() { JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); DataSource dataSource = dataSourceLookup.getDataSource(secondary().getJndiName()); return dataSource; } private static class JndiPropertyHolder { private String jndiName; public String getJndiName() { return jndiName; } public void setJndiName(String jndiName) { this.jndiName = jndiName; } } } 

And then you can follow the manual http://docs.spring.io/spring-data/jpa/docs/1.3.0.RELEASE/reference/html/jpa.repositories.html to use your data sources with jpa repositories.

+6
source

You can use a simple JndiObjectFactoryBean . Just replace DataSourceBuilder with JndiObjectFactoryBean to do the trick.

Java configuration

 @Bean(destroyMethod="") @Primary @ConfigurationProperties(prefix="datasource.primary") public FactoryBean primaryDataSource() { return new JndiObjectFactoryBean(); } @Bean(destroyMethod="") @ConfigurationProperties(prefix="datasource.secondary") public FactoryBean secondaryDataSource() { return new JndiObjectFactoryBean(); } 

The properties

 datasource.primary.jndi-name=jdbc/customer datasource.primary.expected-type=javax.sql.DataSource datasource.secondary.jndi-name=jdbc/project datasource.secondary.expected-type=javax.sql.DataSource 

You can set each JndiObjectFactoryBean property using the @ConfigurationProperties annotation. (See Added expected-type , but you can also set cache or lookup-on-startup , etc.).

Note: when performing a JNDI search, set destroyMethod to "" otherwise you may get a situation where, when the application terminates, your JNDI resource also closes / ends. This is not what you want in a shared environment.

+4
source

It works for me and contains less code.

 @Configuration public class Config { @Value("${spring.datasource.primary.jndi-name}") private String primaryJndiName; @Value("${spring.datasource.secondary.jndi-name}") private String secondaryJndiName; private JndiDataSourceLookup lookup = new JndiDataSourceLookup(); @Primary @Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability public DataSource primaryDs() { return lookup.getDataSource(primaryJndiName); } @Bean(destroyMethod = "") // destroy method is disabled for Weblogic update app ability public DataSource secondaryDs() { return lookup.getDataSource(secondaryJndiName); } } 
+3
source

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


All Articles