2017-01-01 22 views
5

farklı bellek datasources kullanarak birden kalıcılık birimlerinin JPA yapılandırma inşa ediyorum çalışmaz, ancak yapılandırma varlık yöneticisi fabrika fasulye için nitelikli veri kaynağı çözme başarısız aşağıdaki hata ile: BuradaBahar datasources

*************************** 
APPLICATION FAILED TO START 
*************************** 

Description: 

Parameter 0 of method emfb in datasources.Application$PersistenceConfiguration required a single bean, but 2 were found: 
     - ds1: defined by method 'ds1' in class path resource [datasources/Application$PersistenceConfiguration.class] 
     - ds2: defined by method 'ds2' in class path resource [datasources/Application$PersistenceConfiguration.class] 


Action: 

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed 

örnek uygulama

package datasources; 

import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import javax.persistence.PersistenceContextType; 
import javax.sql.DataSource; 
import javax.ws.rs.ApplicationPath; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import org.apache.log4j.Logger; 
import org.glassfish.jersey.server.ResourceConfig; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration; 
import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; 
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
import org.springframework.stereotype.Component; 

@Configuration 
@EnableAutoConfiguration(exclude = { 
//  HibernateJpaAutoConfiguration.class, 
//  DataSourceAutoConfiguration.class 
     JtaAutoConfiguration.class 
}) 
@ComponentScan 
public class Application { 

    public static void main(String[] args) { 

     new SpringApplicationBuilder(Application.class) 
      .build() 
      .run(args); 
    } 

    @Component 
    @Path("/ds") 
    public static class DsApi { 

     private final static Logger logger = Logger.getLogger(DsApi.class); 

     @Autowired(required = false) 
     @Qualifier("ds1") 
     private DataSource ds; 

     @GET 
     public String ds() { 
      logger.info("ds"); 
      return ds.toString(); 
     } 
    } 

    @Component 
    @Path("/em") 
    public static class EmApi { 

     private final static Logger logger = Logger.getLogger(EmApi.class); 

     @PersistenceContext(unitName = "ds2", type = PersistenceContextType.TRANSACTION) 
     private EntityManager em; 

     @GET 
     public String em() { 
      logger.info("em"); 
      return em.toString(); 
     } 
    } 

    @Configuration 
    @ApplicationPath("/jersey") 
    public static class JerseyConfig extends ResourceConfig { 
     public JerseyConfig() { 
      register(DsApi.class); 
      register(EmApi.class); 
     } 
    } 

    @Configuration 
    public static class PersistenceConfiguration { 

     @Bean 
     @Qualifier("ds1") 
     public DataSource ds1() { 
      return new EmbeddedDatabaseBuilder().build(); 
     } 

     @Bean 
     @Qualifier("ds2") 
     public DataSource ds2() { 
      return new EmbeddedDatabaseBuilder().build(); 
     } 

     @Bean 
     @Primary 
     @Autowired 
     public LocalContainerEntityManagerFactoryBean emfb(@Qualifier("ds1") DataSource ds, EntityManagerFactoryBuilder emfb) { 
      return emfb.dataSource(ds) 
        .packages(Application.class) 
        .persistenceUnit("ds1") 
        .build(); 
     } 

     @Bean 
     @Autowired 
     public LocalContainerEntityManagerFactoryBean emfb2(@Qualifier("ds2") DataSource ds, EntityManagerFactoryBuilder emfb) { 
      return emfb.dataSource(ds) 
        .packages(Application.class) 
        .persistenceUnit("ds2") 
        .build(); 
     } 
    } 
} 
olduğunu
+0

Belki de statik bir sınıfta çalışmıyor? – Patrick

+0

Bu DataSource çekirdeklerini rastgele bir türle değiştirmeyi denedim ve bağımlılıklar doğru bir şekilde çözülmedi. Ayrıca aynı hata ile el ile başlatılmış DataSource (oluşturucu yok) döndürmeye çalıştı. –

cevap

3

DataSource'unuzdan birini @Primary olarak bildirin.

@Configuration 
public static class PersistenceConfiguration { 

     @Bean 
     @Primary 
     public DataSource ds1() { 
      return new EmbeddedDatabaseBuilder().build(); 
     } 

     @Bean 
     public DataSource ds2() { 
      return new EmbeddedDatabaseBuilder().build(); 
     } 

     @Bean 
     @Primary 
     @Autowired 
     public LocalContainerEntityManagerFactoryBean emfb(@Qualifier("ds1") DataSource ds, EntityManagerFactoryBuilder emfb) { 
      return emfb.dataSource(ds) 
        .packages(DemoApplication.class) 
        .persistenceUnit("ds1") 
        .build(); 
     } 

     @Bean 
     @Autowired 
     public LocalContainerEntityManagerFactoryBean emfb2(@Qualifier("ds2") DataSource ds, EntityManagerFactoryBuilder emfb) { 
      return emfb.dataSource(ds) 
        .packages(DemoApplication.class) 
        .persistenceUnit("ds2") 
        .build(); 
     } 
} 
+0

Bu, ds1 –

+0

'a gereksinim duyan emfb2'ye ds1 enjekte edecektir. "@Qualifier (" ds2 ")' yi 'emfb2' – Arpit

+2

oluştururken belirtmemeliyiz. Ama Qualifier'ın neden birincil çalışması gerekiyor? Ayrıca, aynı kablolama Birincil olmadan, neden bu ds yöntemleri yerine başka bir tür döndürdüler (Ve tabii ki bu tür tüketmek için emfb yöntemleri refactored) çalıştı? –

2

hata uygulamada bir noktada, bir fasulye enjekte ediliyor belirten olduğu: LocalContainerEntityManagerFactoryBean, bunlardan biri yanı sıra, aşağıdaki @Primary ilan -

Ayrıca aynı tip 2 fasulye DataSource türünde ve adıyla bu noktada numaralı noktada kalifiye olmayacaktır.

Tek bir konumda @Qualifier eklemiş olmanız önemli değil. Enjeksiyon, uygun olmayan bazı diğer konumlarında başarısız oluyor. Bu sizin hatanız değil, çünkü bu konum, Spring Boot'un DataSourceAutoConfiguration numaranızdadır, ki bu, kaydettiğiniz parçanın altında yığın izinizde görebilmeniz gerekir.

DataSourceAutoConfiguration i.e. @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) ürününü hariç tutmanızı öneririz. Aksi takdirde, bu konfigürasyon sadece @Primary yapınız fasulyeye uygulanır. Tam olarak ne olduğunu bilmiyorsanız, DataSource s arasındaki davranışlarda ince ve beklenmedik farklılıklar ortaya çıkarmanız olasıdır.

0

Veri kaynağı çekirdeklerini statik sınıfın dışında bildirmeyi deneyin. I.e doğrudan Application.java