【问题标题】:Spring Boot 2.1.7RELEASE-NoUniqueBeanDefinitionExceptionSpring Boot 2.1.7RELEASE-NoUniqueBeanDefinitionException
【发布时间】: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

但还是出现同样的错误

【问题讨论】:

  • 可能是 &lt;bean primary="true|false"/&gt; 可以帮助或将这些 bean 放入不同的配置文件中。
  • 你也可以使用 Qualifier 来作为你的 bean。
  • 在 sybaseEntityManagerFactory 上添加的主要仍然收到错误 @AlexeyUsharovski
  • 所有工厂也可以试试&lt;property name="persistenceUnitName" value="managerPU" /&gt;

标签: spring spring-boot spring-data-jpa spring-bean spring-orm


【解决方案1】:

Spring boot 正在按类型解决依赖关系,它正在为 javax.persistence.EntityManagerFactory 找到两个实现

  1. sybaseEntityManagerFactory
  2. mssqlEntityManagerFactory

您只需将其中一个 bean 设置为您想要使用的主要 bean

<bean primary="true|false"/>

如下图

<bean id="mssqlEntityManagerFactory" primary="true" 
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <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>

或者您可以有条件地加载一个 bean,这个 URL 可能会对您有所帮助。

【讨论】:

  • 堆栈跟踪是否相同?
  • 好像bean定义的改变没有效果,你能从xml中删除一个bean声明进行调试
猜你喜欢
  • 1970-01-01
  • 2015-09-12
  • 2017-01-18
  • 2018-01-09
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-02
相关资源
最近更新 更多