NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean

隐身守侯 提交于 2019-12-20 12:33:46

问题


I have 2 separate databases and I am trying to access them in repositories. Unfortunately I am receiving the following exception.

Things I have tried

  • have tried making one of the bean as Primary.
  • have used PersistenceContext as can be seen in code below.

My ExceptionTrace

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.crud.repository.mymerkNew.OrderRepository com.crud.controller.OrderController.nextGenorder; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: mymerkLimsEntityManagerFactory,nextGenEntityManagerFactory
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:961)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:950)
    at com.mymerkbiotech.orange.crud.Application.main(Application.java:24)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mymerkbiotech.orange.crud.repository.mymerkNew.OrderRepository com.mymerkbiotech.orange.crud.controller.OrderController.nextGenorder; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: mymerkLimsEntityManagerFactory,nextGenEntityManagerFactory
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'orderRepository': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: mymerkLimsEntityManagerFactory,nextGenEntityManagerFactory
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:357)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1127)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1051)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 18 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: mymerkLimsEntityManagerFactory,nextGenEntityManagerFactory
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:572)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:531)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:697)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:670)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354)
    ... 29 more

My order controller which is simply Autowiring Repository

@RestController
@RequestMapping("/Order")
public class OrderController {

    @Autowired
    private OrderRepository nextGenorder;

My order Repository has

@Repository
public class OrderRepository extends AbstractRepository<Order> implements
        OrderRepositoryInterface {
    private static final String SELECT_QUERY = "select p from v_orders p";
    @PersistenceContext(name = "nextGenEntityManagerFactory")
    private EntityManager nextGenEntityManagerFactory;;

    public EntityManager getEntityManager() {
        return nextGenEntityManagerFactory;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.nextGenEntityManagerFactory = entityManager;
    }

    public List<Order> selectAll() {
        javax.persistence.Query query = nextGenEntityManagerFactory
                .createQuery(SELECT_QUERY);
        List<Order> order = query.getResultList();
        return order;
    }

My FirstConfig file

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "xx.xx.xx.crud.repository.running", entityManagerFactoryRef = "nextGenEntityManagerFactory", transactionManagerRef = "transactionManagerOne")
@PropertySource("classpath:application.properties")
public class NextGenDbConfig {

    @Value("${spring.datasourcemymerkNew.driver-class-name}")
    String driverClassName = "";
    @Value("${spring.datasourcemymerkNew.url}")
    String url = "";
    @Value("${spring.datasourcemymerkNew.username}")
    String userName = "";
    @Value("${spring.datasourcemymerkNew.password}")
    String password = "";
    @Autowired
    @Qualifier("jpaNextGenVendorApapter")
    JpaVendorAdapter jpaNextGenVendorApapter;

    @Bean(name = "nextGenDataSource")
    @Primary
    public DataSource nextGenDataSource() {
        return DataSourceBuilder.create().url(url)
                .driverClassName(driverClassName).username(userName)
                .password(password).build();
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean nextGenEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

        factoryBean.setDataSource(nextGenDataSource());
        factoryBean.setJpaVendorAdapter(jpaNextGenVendorApapter);
        factoryBean.setPackagesToScan(R.nextGenDB_PACKAGE);
        factoryBean.setPersistenceUnitName("nextGenPersistenceUnit");
        factoryBean.setJpaProperties(additionalProperties());

        return factoryBean;
    }

    @Bean
    PlatformTransactionManager transactionManagerOne() {
        return new JpaTransactionManager(nextGenEntityManagerFactory()
                .getObject());
    }

    @Bean(name = "jpaNextGenVendorApapter")
    @Primary
    public JpaVendorAdapter jpaNextGenVendorAdapter() {
        HibernateJpaVendorAdapter jpaNextGenVendorAdapter = new HibernateJpaVendorAdapter();
        jpaNextGenVendorAdapter.setShowSql(true);
        jpaNextGenVendorAdapter.setGenerateDdl(true);
        jpaNextGenVendorAdapter.setDatabase(Database.MYSQL);
        return jpaNextGenVendorAdapter;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect",
                "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator() {
        return new HibernateExceptionTranslator();
    }

}

and second config

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.mymerkbiotech.orange.crud.repository.running", entityManagerFactoryRef = "mymerkLimsEntityManagerFactory", transactionManagerRef = "transactionManagertwo")
@PropertySource("classpath:application.properties")
public class mymerkDbConfig {

    @Value("${spring.datasourcemymerkLims.driver-class-name}")
    String driverClassName = "";
    @Value("${spring.datasourcemymerkLims.url}")
    String url = "";
    @Value("${spring.datasourcemymerkLims.username}")
    String userName = "";
    @Value("${spring.datasourcemymerkLims.password}")
    String password = "";
    @Autowired
    @Qualifier("jpamymerkVendorAdapter")
    JpaVendorAdapter mymerkVendorAdapter;

    @Bean(name = "mymerklimsDataSource")
    public DataSource mymerklimsDataSource() {
        return DataSourceBuilder.create().url(url)
                .driverClassName(driverClassName).username(userName)
                .password(password).build();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean mymerkLimsEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();

        factoryBean.setDataSource(mymerklimsDataSource());

        factoryBean.setJpaVendorAdapter(mymerkVendorAdapter);
        factoryBean.setPackagesToScan(R.mymerkDB_PACKAGE);
        factoryBean.setPersistenceUnitName("mymerklimsPersistenceUnit");
        factoryBean.afterPropertiesSet();

        return factoryBean;
    }

    @Bean
    PlatformTransactionManager transactionManagerTwo() {
        return new JpaTransactionManager(mymerkLimsEntityManagerFactory()
                .getObject());
    }

    @Bean(name = "jpamymerkVendorAdapter")
    public JpaVendorAdapter jpamymerkVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setShowSql(true);
        jpaVendorAdapter.setGenerateDdl(true);
        jpaVendorAdapter.setDatabase(Database.MYSQL);
        return jpaVendorAdapter;
    }

    Properties additionalProperties() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
        properties.setProperty("hibernate.dialect",
                "org.hibernate.dialect.MySQL5Dialect");
        return properties;
    }

}

I tried debugging in PersistenceAnnotationBeanPostProcessor but was lost soon.


回答1:


I think you should be naming your LocalContainerEntityManagerFactoryBean's in both configurations. So it should look like:

@Bean(name = "nextGenEntityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean nextGenEntityManagerFactory() {

for the first one and

@Bean(name = "gatcLimsEntityManagerFactory") 
public LocalContainerEntityManagerFactoryBean gatcLimsEntityManagerFactory() {

for the second.




回答2:


This exception can also be tackled by exluding JPA autoconfiguration. Usually when there are two Entity Managers the configuration is done manualy anyway, so there is no point in relying on autoconfiguration for that.

DataSourceAutoconfiguration should be excluded and everything which inherits from JpaBaseConfiguration

@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration} 
public class MySpringApp() {}

or

@SpringBootAutoconfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration)
public class MySpringApp() {}


来源:https://stackoverflow.com/questions/32114558/nouniquebeandefinitionexception-no-qualifying-bean-of-type-javax-persistence-e

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!