Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using 2 beans of the same type: javax.sql.DataSource in Spring

Tags:

java

spring

I am developing a Spring Boot based application in which I would like to create 2 beans: One will point to 'Oracle' database; the other will point to Hive. I've declared them as follows:

public @Bean
BoneCPDataSource metadataDataSource() {
    BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
    boneCPDataSource.setDriverClass(getDriver());
    boneCPDataSource.setJdbcUrl(getJdbcUrl());
    boneCPDataSource.setUser(getUser());
    boneCPDataSource.setPassword(getPassword());
    boneCPDataSource.setMaxConnectionsPerPartition(5);
    boneCPDataSource.setPartitionCount(5);
    return boneCPDataSource;
}

public @Bean
BasicDataSource hiveDataSource() {
    BasicDataSource basicDataSource = new BasicDataSource();

    // Note: In a separate command window, use port forwarding like this:
    //
    // ssh -L 127.0.0.1:9996:<server>:<port> -l <userid> <server>
    //
    // and then login as the generic user.

    basicDataSource.setDriverClassName("org.apache.hadoop.hive.jdbc.HiveDriver");
    basicDataSource.setUrl("jdbc:hive://127.0.0.1:9996:10000/mytable");
    return basicDataSource;
}

Problem is at the startup I am getting this:

Exception in thread "main"
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration':
Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private javax.sql.DataSource
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration.dataSource;
nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type [javax.sql.DataSource] is defined: expected
single matching bean but found 2: metadataDataSource,hiveDataSource

Mainly because both of them inherit from javax.sql.DataSource. What's the best way to fix this?


EDIT:

Now I've declared them as follows:

public @Bean (name="metadataDataSource")
BoneCPDataSource metadataDataSource() {
    BoneCPDataSource boneCPDataSource = new BoneCPDataSource();
    boneCPDataSource.setDriverClass(getDriver());
    boneCPDataSource.setJdbcUrl(getJdbcUrl());
    boneCPDataSource.setUser(getUser());
    boneCPDataSource.setPassword(getPassword());
    boneCPDataSource.setMaxConnectionsPerPartition(5);
    boneCPDataSource.setPartitionCount(5);
    return boneCPDataSource;
}

public @Bean (name="hiveDataSource")
BasicDataSource hiveDataSource() {
    BasicDataSource basicDataSource = new BasicDataSource();

    // Note: In a separate command window, use port forwarding like this:
    //
    // ssh -L 127.0.0.1:9996:<server>:<port> -l <userid> <server>
    //
    // and then login as the generic user.

    basicDataSource.setDriverClassName("org.apache.hadoop.hive.jdbc.HiveDriver");
    basicDataSource.setUrl("jdbc:hive://127.0.0.1:9996:10000/mytable");
    return basicDataSource;
}

And got this exception:

Exception in thread "main"
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration':
Injection of autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private javax.sql.DataSource
org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration.dataSource;
nested exception is
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type [javax.sql.DataSource] is defined: expected
single matching bean but found 2: metadataDataSource,hiveDataSource

The other classes are referring to these beans as follows:

public class MetadataProcessorImpl implements MetadataProcessor {

@Autowired
@Qualifier("metadataDataSource")
BoneCPDataSource metadataDataSource;

@Controller public class HiveController {

@Autowired
@Qualifier("hiveDataSource")
BasicDataSource hiveDataSource;
like image 265
DilTeam Avatar asked May 15 '14 19:05

DilTeam


People also ask

Can we define two beans with same name in spring?

Can I define spring bean twice with same name in different bean definition file? Yes. When the second bean definition file loads, it overrides the definition from the first file. The main objective of this behavior is to ovrrride the previously loaded bean definition.

Can we have multiple beans of a same type in a class?

The limitation of this approach is that we need to manually instantiate beans using the new keyword in a typical Java-based configuration style. Therefore, if the number of beans of the same class increases, we need to register them first and create beans in the configuration class.

Does spring allow more than one bean definition in the configuration?

Spring Couldn't autowired,there is more than one bean of `` type. Bookmark this question.

Can we have same bean name in spring boot?

Spring beans are identified by their names within an ApplicationContext. Thus, bean overriding is a default behavior that happens when we define a bean within an ApplicationContext which has the same name as another bean. It works by simply replacing the former bean in case of a name conflict.


1 Answers

Set one of the beam as @Primary as described in the section 67.2 Configure Two DataSources

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-two-datasources

like image 165
Danilo Avatar answered Sep 24 '22 09:09

Danilo