【发布时间】:2019-09-25 08:05:10
【问题描述】:
在将 Spring 迁移到 Spring Boot2.1.7 时遇到 NoUniqueBeanDefinitionException。Bean 配置是 xml 文件。我们使用 @ImportResources 注释添加了该 xml 文件
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.7.RELEASE)
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
62 SybaseUnit INFO [main] openjpa.Enhance - You have enabled runtime enhancement, but have not specified the set of persistent classes. OpenJPA must look for metadata for every loaded class, which might increase class load times significantly.
23 SybaseUnit WARN [main] openjpa.Runtime - An error occurred while registering a ClassTransformer with PersistenceUnitInfo: name 'SybaseUnit', root URL [Service/target/classes/]. The error has been consumed. To see it, set your openjpa.Runtime log level to TRACE. Load-time class transformation will not be available.
30 SybaseUnit WARN [main] openjpa.Runtime - Could not create the optional validation provider. Reason returned: "A default ValidatorFactory could not be created."
2 MssqlUnit INFO [main] openjpa.Enhance - You have enabled runtime enhancement, but have not specified the set of persistent classes. OpenJPA must look for metadata for every loaded class, which might increase class load times significantly.
1 MssqlUnit WARN [main] openjpa.Runtime - An error occurred while registering a ClassTransformer with PersistenceUnitInfo: name 'MssqlUnit', root URL [Service/target/classes/]. The error has been consumed. To see it, set your openjpa.Runtime log level to TRACE. Load-time class transformation will not be available.
2 MssqlUnit WARN [main] openjpa.Runtime - Could not create the optional validation provider. Reason returned: "A default ValidatorFactory could not be created."
[WARNING]
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:543)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataAccessService': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: expected single matching bean but found 2: sybaseEntityManagerFactory,mssqlEntityManagerFactory
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:357)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1416)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:743)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:390)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
at com.ge.hcit.xer.app.services.api.XERServiceMain.main(XERServiceMain.java:41)
... 6 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.persistence.EntityManagerFactory' available: expected single matching bean but found 2: sybaseEntityManagerFactory,mssqlEntityManagerFactory
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:180)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354)
... 21 more
XML bean 配置
<bean id="mssqlDataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
depends-on="localConfig">
</bean>
<bean id="mssqlTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="mssqlEntityManagerFactory" />
</bean>
<bean id="mssqlEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" primary ="true">
<property name="dataSource" ref="mssqlDataSource" />
<property name="jpaVendorAdapter" ref="openJpaVendorAdapter" />
<property name="persistenceUnitName" value="MssqlUnit" />
<property name="packagesToScan" >
<list>
<value>com.datasource.jpa.dto</value>
</list>
</property>
</bean>
</beans>
<bean id="sybaseDataSource" class="org.apache.tomcat.jdbc.pool.DataSource"
depends-on="localConfig">
</bean>
<bean id="sybaseTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="sybaseEntityManagerFactory" />
<property name="persistenceUnitName" value="SybaseUnit" />
</bean>
<bean id="sybaseEntityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="sybaseDataSource" />
</bean>
同样排除Spring boot主类中的HibernateJpaAutoConfiguration.class 请参考以下链接 stackoverflow link
数据访问服务
@Repository
public class DataAccessService
{
private static final Logger LOGGER = Logger.getLogger(DataAccessService.class);
private static final String DEFAULT_HOSTNAME = "localhost";
@PersistenceContext(unitName="MssqlUnit")
private EntityManager entityManager;
如何在 xml 文件配置中做同样的事情
如何在不删除 xml bean 定义的情况下将 bean 设置为“mssqlEntityManagerFactory”。以下是制作的
1.add Primary ="true"
2.add unitName="MssqlUnit"
3.add Qualifer
但还是出现同样的错误
【问题讨论】:
-
可能是
<bean primary="true|false"/>可以帮助或将这些 bean 放入不同的配置文件中。 -
你也可以使用
Qualifier来作为你的 bean。 -
在 sybaseEntityManagerFactory 上添加的主要仍然收到错误 @AlexeyUsharovski
-
所有工厂也可以试试
<property name="persistenceUnitName" value="managerPU" />。
标签: spring spring-boot spring-data-jpa spring-bean spring-orm