2016-05-17 14 views
1

Ich versuche, zwei Datenquellen mit meiner SpringBoot-Anwendung zu verwenden, und kann die zweite Datenquelle nicht zum Autowire abrufen. Ich habe viele Dinge ausprobiert, aber das ist die nächste, die ich gekommen sind:SpringBoot und SpringJDBC mehrere Datenquellen

Meine Yaml Datei:

spring: 
    first-datasource: 
    url: MyURLString1 
    username: User 
    password: Password 
    driver-class-name: oracle.jdbc.OracleDriver 
    second-datasource: 
    url: MyURLString2 
    username: User 
    password: Password 
    driver-class-name: oracle.jdbc.OracleDriver 

Meine Anwendungsklasse:

@SpringBootApplication 
public class MyApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(MyApplication.class, args); 
    } 

    @Bean 
    @Primary 
    @ConfigurationProperties(prefix = "spring.first-datasource") 
    public DataSource firstDataSource() { 
     return DataSourceBuilder.create().build(); 
    } 

    @Bean 
    @ConfigurationProperties(prefix = "spring.second-datasource") 
    public DataSource secondDataSource() { 
     return DataSourceBuilder.create().build(); 
    } 
} 

Und mein DAO Endlich:

@Repository 
public class MyDao { 
    private static final String FIRST_SELECT = "select * from SomeTableInDB1"; 
    private static final String SECOND_SELECT = "select * from AnotherTableInDB2"; 

    @Autowired 
    private JdbcTemplate firstJdbcTemplate; 
    @Autowired 
    @Qualifier("secondDataSource") 
    private JdbcTemplate secondJdbcTemplate; 

    List<DB1Entity> getDB1Entity(Long id) { 
     return firstJdbcTemplate.query(FIRST_SELECT, new Object[] {id}, new BeanPropertyRowMapper(DB1Entity.class)); 
    } 

    List<DB2Entity> getDB2Entity(Long id) { 
     return secondJdbcTemplate.query(SECOND_SELECT, new Object[] {id}, new BeanPropertyRowMapper(DB2Entity.class)); 
    } 
} 

Dies ist die nächste, die ich bisher gekommen bin. Ich sage, dass es am nächsten ist, denn wenn ich den @Qualifier entferne, dann funktionieren beide meine Dao-Methoden tatsächlich, vorausgesetzt, dass die SECOND_SELECT-Anweisung gültige SQL für meinen DB1 ist. Sobald ich den @Qualifier für meine nicht-primäre Datenquelle einfüge, erhalte ich einen Autowarefehler, weil Spring ein Datasouce-Objekt und kein JdbcTemplate-Objekt erwartet. Das ist seltsam für mich, da es mit der primären Datenquelle funktioniert.

Hier ist mein Fehler:

nicht Feld autowire konnte: privat org.springframework.jdbc.core.JdbcTemplate org.my.classpath.secondJdbcTemplate; verschachtelte Ausnahme ist org.springframework.beans.factory.NoSuchBeanDefinitionException: Kein qualifizierendes Bean vom Typ [org.springframework.jdbc.core.JdbcTemplate] gefunden für Abhängigkeit: erwartet mindestens 1 Bean, das sich als Autowire-Kandidat für diese Abhängigkeit qualifiziert. Dependency Anmerkungen: {@ org.springframework.beans.factory.annotation.Autowired (required = true), @ org.springframework.beans.factory.annotation.Qualifier (Wert = secondDataSource)}

+1

Sie erstellen die Bean vom Typ DataSource, aber Autowire JdbcTemplate.Sie sollten wahrscheinlich so etwas haben wie 'private JdbcTemplate jdbcTemplate1; private JdbcTemplate jdbcTemplate2; @Autowired @Qualifier ("firstDataSource") public void setDataSource (Datasource Datasource) { this.jdbcTemplate1 = new JdbcTemplate (Datasource); } @Autowired @Qualifier ("secondDataSource") public void setDataSource (Datasource Datasource) { this.jdbcTemplate2 = new JdbcTemplate (Datasource); } ' – lenach87

+0

Ich hatte etwas fast identisch versucht, aber bekam eine Fehlermeldung über eine Null-URL. Ich muss mich etwas vertippt haben, weil ich deinen Code kopiert habe und es funktioniert. Vielen Dank. Ich bin sicher, es war etwas dummes. – Gremash

+0

@ lenach87 Das ist die richtige Lösung und ich denke, die Frage ist gut. Schreibe eine Antwort und ich werde sie als die richtige markieren. – Gremash

Antwort

1

Sie erstellen die Bohne vom Typ DataSource, aber versuchen Sie Autowire JdbcTemplate, die eine Abweichung ist. Sie sollte wohl so etwas wie dies

private JdbcTemplate jdbcTemplate1; 
private JdbcTemplate jdbcTemplate2; 

@Autowired 
@Qualifier("firstDataSource") 
public void setDataSource(DataSource dataSource){ 
    this.jdbcTemplate1=new JdbcTemplate(dataSource); 
} 

@Autowired 
@Qualifier("secondDataSource") 
public void setDataSource(DataSource dataSource){ 
    this.jdbcTemplate2=new JdbcTemplate(dataSource); 
} 
0

Idealerweise aber kein Mandat, eine der Datenquellen sollte arbeitet primär für die meist Standard-Verdrahtung über Anmerkungen markiert werden. Außerdem müssen wir TransactionManager für jede der Datenquellen separat erstellen, andernfalls würde Spring nicht wissen, wie Transaktionen durchgesetzt werden. Im Folgenden finden Sie ein vollständiges Beispiel dafür, wie dies gemacht werden sollte

@Primary 
@Bean(name = "dataSource") 
@ConfigurationProperties(prefix="datasource.mysql") 
public DataSource dataSource() { 
    return DataSourceBuilder.create().build(); 
} 

@Primary 
@Bean(name = "transactionManager") 
public DataSourceTransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource) { 
    return new DataSourceTransactionManager(); 
} 

@Bean(name = "postGresDataSource") 
@ConfigurationProperties(prefix="datasource.postgres") 
public DataSource postgresDataSource() { 
    return DataSourceBuilder.create().build(); 
} 

@Bean(name = "postGresTransactionManager") 
public DataSourceTransactionManager transactionManager(@Qualifier("postGresDataSource") DataSource dataSource) { 
    return new DataSourceTransactionManager(); 
} 

@Transactional(transactionManager="postGresTransactionManager") 
public void createCustomer(Customer cust) { 
    customerDAO.create(cust); 
} 

// specifying a transactionManager attribute is optional if we 
// want to use the default transactionManager since we 
// already marked one of the TM above with @Primary 
@Transactional 
public void createOrder(Order order) { 
    orderDAO.create(order); 
} 

Hoffen, dass dies hilft.

0

Hier bietet auch eine andere "nicht-arbeit Situation, die mir mehrere Tage verwirrte:

wenn zwei Datenquellen gleichen Typs in Springboot Anwendung konfigurierend, die @Qualifier nicht wie erwartet funktionieren richtige Bohnen zu holen . Es verhält sich so, als ob es nicht von Spring Framework erkannt wird.

Der Grund ist, wenn @SpringbootApplication Annotation verwendet wird, die @EnableAutoConfiguration Annotation enthält, die in Springboot Datenquellen für Benutzer automatisch konfigurieren wird.

würde dies das Verhalten @Qualifier schrecklich beeinflussen.

Verwandte Themen