I had asked a question here but was incomplete and was marked as duplicate here
So based on the question already asked - one particular answer by @surasin-tancharoen seemed to be what I needed.
However trying that too gives me a NullPointerException
since the data source is never created / injected.
Here are the details:
In the below code I have defined 2 beans. I have defined both datasources with @Qualifier
annotation and @ConfigurationProperties
to read the JNDI name from properties file.
@Configuration
public class DataSourceConfig {
@Bean
@Primary
@Qualifier("ds1")
@ConfigurationProperties(prefix="spring.datasource1")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Qualifier("ds2")
@ConfigurationProperties(prefix="spring.datasource2")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
In application.properties
:
spring.datasource1.jndi-name=AbcDS
spring.datasource2.jndi-name=XyzDS
Then in my DAO - I am trying to use this datasource:
@Autowired
@Qualifier("ds1")
DataSource dataSource;
However the datasource is not injected since I get a NullPointerException
at this line of code:
conn = dataSource.getConnection();
All of this is being attempted by deploying the Spring Boot application to Weblogic 12c
The solution is related to incorrect usage of 'DataSourceBuilder' which should not be used for a JNDI datasource.
Here is how I got it working :
( deploying spring boot war on weblogic and consuming datasources defined in weblogic )
First we specify the datasources defined in weblogic - here we specify the JNDI name of the datasources defined in weblogic:
spring.datasource.xyz.jndi-name=XYZDS
spring.datasource.test.jndi-name=TESTDS
This is where the Datasource is created using above defined properties and exposed:
We are injecting the properties from application.properties into string variables to store JNDI names of datasources.
@Configuration
public class DataSourceConfig {
@Value( "${spring.datasource.xyz.jndi-name}" )
private String xyzJndiName;
@Value( "${spring.datasource.test.jndi-name}" )
private String testJndiName;
@Bean(name = "XyzDataSource")
public DataSource getXyzDataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(xyzJndiName);
}
@Bean(name = "TestDataSource")
public DataSource getTestDataSource() throws Exception {
JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
return dataSourceLookup.getDataSource(testJndiName);
}
A few key points to note :
We should not be using 'DataSourceBuilder' for a JNDI datasource - it will not work.
This was the reason why it was not working in my case .
Now I am using 'JndiDataSourceLookup' which does the trick.
Another thing to note is that we need to use the standard @Bean annotation with the attribute 'name'.
This will be important in the piece of code that consumes this datasource.
So now the datasources are created successfully and exposed.
OK time to consume :
@Repository
public class SomeDaoImpl {
@Autowired
@Qualifier("XyzDataSource")
DataSource dataSource;
@Override
public List <String> create(Employee request) {
Connection conn = null;
conn = dataSource.getConnection();
Here we are using the @Qualifier annotation to pickup the appropriate datasource .
Thats it - this works now.
I tried it with the other data source - it worked as well.
NOTE:
I would not like to accept my own answer - so I will wait for a couple of days if anyone else has a better and more elegant solution please answer - will be happy to accept your answer rather than answering my own question and accepting !