问题
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