2015-01-08 16 views
12

Tôi đang sử dụng cấu hình dựa trên Spring Java để định cấu hình nhiều cơ sở dữ liệu với dữ liệu Spring. Trong tệp cấu hình, tôi đang tạo hai data source cho MySQLMSSQL-Server. Khi cố gắng để tiêm phụ thuộc vào người quản lý đơn vị sử dụng @Resource chú tôi đang nhận được ngoại lệ sau đây:Chú thích tài nguyên: Không có loại đậu đủ điều kiện [javax.sql.DataSource] được định nghĩa: bean kết hợp đơn dự kiến ​​nhưng tìm thấy 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) 

Tiếp theo là mã của tôi:

@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; 
} 

Tôi cũng cố gắng sử dụng @Qualifier chú thích như đề nghị tôi liên kết này nhưng vẫn gặp lỗi. Using 2 beans of the same type: javax.sql.DataSource in Spring

Trả lời

4

tôi đã cùng một vấn đề và tìm thấy bài cũ này mà giải thích nó:

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

Dường như nếu bạn cần nhiều nguồn dữ liệu, mùa xuân Boot magic chạy ra ngoài, và bạn phải mất qua cấu hình theo cách thủ công.

Trong trường hợp của tôi, tôi đã phải thay đổi EnableAutoConfiguration để tiếp nhận các nguồn dữ liệu và quản lý giao dịch cấu hình bản thân mình:

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

Dường như sự kỳ diệu mùa xuân Boot chạy ra tại thời điểm tôi đã phải sử dụng nhiều nguồn dữ liệu ...

7

tôi đã cùng một vấn đề và sau rất nhiều đau đầu tôi stumbled khi doc này khiến tôi cảm thấy thực sự câm :(

Tất cả bạn cần là @Primary trên một trong DataSource và mùa xuân của bạn -Bo ot sẽ không bị lẫn lộn nữa ... Đây là một trong những cấu hình của tôi ... Phần còn lại là khá nhiều giống hệt nhau, chỉ vào DBS khác và không có @Primary trên chúng ...

@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: Quên đề cập: Có thể là do cách thức các lớp cấu hình của tôi được thực hiện, phương pháp loại trừ một số lớp trên @EnableAutoConfiguration không hoạt động cho tôi ...

+0

Tôi đã thêm chỉ thị @Primary nhưng khi tôi làm người quản lý giao dịch, cả hai nhà máy phiên của họ đều sử dụng nguồn dữ liệu chính. Có cách nào để nói cụ thể cho sessionfactory sử dụng nguồn dữ liệu nào không? – Sakib

+0

Chúng tôi có thể cần một chút mã của bạn để tìm ra từ, như bạn có thể thấy trong đoạn mã trên, trình quản lý phiên được chỉ định trong quá trình tạo trình quản lý giao dịch. –

4

Tôi là trường hợp của tôi, cấu hình nằm trên tệp xml, vì vậy Tôi chỉ phải thêm primary = "true" vào thẻ bean của một trong các nguồn dữ liệu được xác định.

Các vấn đề liên quan