2017-01-01 5 views
5

私は別のインメモリデータソースを使用して、複数の永続性ユニットとJPA構成を構築してるでは動作しませんが、構成がエンティティマネージャファクトリBeanの資格データソースを解決失敗します次のエラーと:ここ春は、データソース

*************************** 
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 

は、サンプルアプリケーション

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(); 
     } 
    } 
} 
です3210
+0

それは静的クラスで動作していない可能性がありますか? – Patrick

+0

これらのDataSource Beanを任意の型に置き換えようとしたときに、依存関係が正しく解決されたため、できませんでした。また、同じエラーで手動でインスタンス化されたDataSource(Builderなし)を返そうとしました。 –

答えて

3

DataSourceのいずれかを@Primaryと宣言してください。

また、同じタイプの2つの豆た - LocalContainerEntityManagerFactoryBean、次のように、同様にそれらのいずれか@Primaryを宣言する:エラーがアプリケーションの中でいくつかの点で、Beanが注入されていること

@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

これは、ds2にds2を注入します。これはds2を必要とします。 –

+0

'emfb2'を作成中に' @Qualifier( "ds2") 'を指定するべきではありません。 – Arpit

+2

本当に、あなたは正しいです!しかし、修飾子がプライマリの仕事を必要とするのはなぜですか?また、なぜこれらのdsメソッドが他の型を返すのであれば、同じワイヤリングがプライマリなしで正常に動作しました(もちろんemfbメソッドはその型を消費するようにリファクタリングされました)? –

2

を示していますタイプDataSourceであり、その時点でという名前で修飾されていないです。

@Qualifierを1か所に追加しても問題ありません。適格でないの場所で注射が失敗しています。その場所はSpring BootのDataSourceAutoConfigurationにあり、あなたが投稿した部分の下のスタックトレースに表示されるはずなので、あなたのせいではありません。

DataSourceAutoConfiguration、つまり@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)を除外することをおすすめします。それ以外の場合は、この構成は、@PrimaryのBeanにのみ適用されます。それが何であるかを正確に把握していない限り、あなたのDataSourceとの間で微妙で予想外の動作の違いが生じる可能性があります。

0

静的クラス以外のデータソースBeanを宣言してください。私は直接Application.javaで