2015-01-08 10 views
12

Utilizzo la configurazione Spring Java Based per configurare più database con Spring Data. Nel file di configurazione sto creando due data source per MySQL e MSSQL-Server. Quando si cerca di iniettare la dipendenza al gestore di entità utilizzando @Resource annotazione sto ottenendo seguente eccezione:Annotazione risorsa: Nessun bean qualificante di tipo [javax.sql.DataSource] è definito: singolo bean di corrispondenza previsto ma trovato 2

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: mysql_datasource,secure_datasource 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016) 
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904) 
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:815) 
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:743) 

seguito è il mio codice:

@Bean(name="secure_datasource") 
public DataSource dataSource(){ 
    try{ 
     ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
     dataSource.setJdbcUrl(environment.getProperty("sc.db.url")); 
     dataSource.setDriverClass(environment.getProperty("sc.db.driver.class")); 
     dataSource.setUser(environment.getProperty("sc.db.username")); 
     dataSource.setPassword(environment.getProperty("sc.db.password")); 
     dataSource.setIdleConnectionTestPeriod(60); 
     dataSource.setMaxPoolSize(10); 
     dataSource.setMaxStatements(7); 
     dataSource.setMinPoolSize(1); 
     return dataSource; 
    }catch(Exception ex){ 
     throw new RuntimeException(ex); 
    } 
} 

................. 

@Bean(name="mysql_datasource") 
public DataSource dataSource(){ 
    try{ 
     ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
     dataSource.setJdbcUrl(environment.getProperty("db.url")); 
     dataSource.setDriverClass(environment.getProperty("db.driver.class")); 
     dataSource.setUser(environment.getProperty("db.username")); 
     dataSource.setPassword(environment.getProperty("db.password")); 
     dataSource.setIdleConnectionTestPeriod(60); 
     dataSource.setMaxPoolSize(100); 
     dataSource.setMaxStatements(50); 
     dataSource.setMinPoolSize(10); 
     return dataSource; 
    }catch(Exception ex){ 
     throw new RuntimeException(ex); 
    } 
} 

....... 

@Resource(value="mysql_datasource") 
@Bean(name="entity_manager_factory") 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource){ 
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean(); 
    factoryBean.setDataSource(dataSource); 
    factoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); 
    factoryBean.setPackagesToScan(environment.getProperty("package.scan")); 
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter); 
    return factoryBean; 
} 

Sto anche cercando di utilizzare @Qualifier annotazioni come suggeriscono i questo link , ma continua a ricevere errori. Using 2 beans of the same type: javax.sql.DataSource in Spring

risposta

4

Ho avuto lo stesso problema e abbiamo trovato questo vecchio post che ha spiegato:

http://xantorohara.blogspot.ch/2013/11/spring-boot-jdbc-with-multiple.html

Sembra che se avete bisogno di più fonti di dati, la magia Stivale Primavera si esaurisce, e si deve prendere sopra la configurazione manualmente.

Nel mio caso, ho dovuto modificare l'EnableAutoConfiguration ad assumere la configurazione di origine dati e gestione delle transazioni me stesso:

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class}) 

Sembra che la magia primavera Boot corse fuori al punto che ho dovuto utilizzare più fonti di dati ...

7

ho avuto lo stesso problema e dopo un sacco di mal di testa io siamo capitati questo doc che mi ha fatto sentire veramente stupido :(

Tutto ciò che serve è @Primary su uno dei tuoi DataSources e Primavera -BO ot non si confonderà più ... Ecco una delle mie configurazioni ... Il resto sono praticamente identiche, indicando altri DB e senza @Primary su di loro ...

@Configuration 
@EnableTransactionManagement 
@EntityScan(basePackages = {"somepackage.entities"}) 
@EnableJpaRepositories(entityManagerFactoryRef = "emfDB1", transactionManagerRef = "tmDB1", basePackages = {"somepackage.repositories"}) 
class PersistenceDB1 { 
    @Bean 
    @Primary 
    DataSource dsDB1() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setUrl("jdbc:mysql://someserver:3306/proativo"); 
     dataSource.setUsername("username"); 
     dataSource.setPassword("password"); 
     dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 
     return dataSource; 
    } 

    @Bean 
    @Primary 
    LocalContainerEntityManagerFactoryBean emfDB1() { 
     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     entityManagerFactoryBean.setDataSource(dsDB1()); 
     entityManagerFactoryBean.setJpaVendorAdapter(new EclipseLinkJpaVendorAdapter()); 

     entityManagerFactoryBean.setPersistenceXmlLocation("classpath:META-INF/DB1-persistence.xml"); 

     Properties jpaProperties = new Properties(); 
     jpaProperties.put("eclipselink.weaving", "false"); 
     jpaProperties.put("eclipselink.logging.level", "SEVERE"); // SEVERE/FINEST 

     entityManagerFactoryBean.setJpaProperties(jpaProperties); 
     return entityManagerFactoryBean; 
    } 

    @Bean 
    @Primary 
    JpaTransactionManager tmDB1() { 
     JpaTransactionManager transactionManager = new JpaTransactionManager(); 
     transactionManager.setEntityManagerFactory(emfDB1().getNativeEntityManagerFactory()); 
     return transactionManager; 
    } 
} 

Edit: Ho dimenticato di menzionare: Probabilmente a causa del modo in cui le mie classi di configurazione sono state eseguite, il metodo di esclusione di alcune classi su @EnableAutoConfiguration non ha funzionato per me ...

+0

Ho aggiunto la direttiva @Primary ma quando eseguo il gestore transazioni, entrambe le rispettive factory di sessione utilizzano l'origine dati primaria. C'è un modo per dire specificamente a sessionfactory di usare quale origine dati? – Sakib

+0

Probabilmente abbiamo bisogno di un po 'del codice per capire perché, come puoi vedere nel codice precedente, il gestore di sessione è specificato nella creazione del gestore transazioni. –

4

Nel mio caso, la configurazione era su un file xml, quindi Devo solo aggiungere il primario = "true" al tag bean di una delle origini dati definite.

Problemi correlati