首页 文章

没有类型'javax.persistence.EntityManager'的限定bean可用:期望的单个匹配bean但找到2

提问于
浏览
3

我有两个实体管理器配置用于两个独立的数据库但是当我尝试自动连接实体管理器来配置我的GraphQLExecutor bean时,我得到一个异常,说明有两个bean符合条件,即使我已经指定了一个单元名称在PersistenceContext中 .

Exception

org.springframework.beans.factory.BeanCreationException:创建名为'graphQLExecutor'的bean时出错:资源依赖注入失败;嵌套异常是org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有类型'javax.persistence.EntityManager'的限定bean可用:期望的单个匹配bean但找到2:org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework组织中org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:321)〜[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]的.orm.jpa.SharedEntityManagerCreator#1 . springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory .doCreateBean(AbstractAutowireCapableBeanFactory.java:553)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableB) eanFactory.java:483)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:306)〜[ spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)〜[spring-beans-4.3.9.RELEASE .jar:4.3.9.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.beans.factory . org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicatio)中的support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] nContext.java:867)〜[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)〜[spring-context -4.3.9.RELEASE.jar:4.3.9.RELEASE] at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)~ [spring-boot-1.5.4.RELEASE.jar: 1.5.4.RELEASE] org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] org.springframework.boot.SpringApplication .refreshContext(SpringApplication.java:360)[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE] org.springframework.boot.SpringApplication.run(SpringApplication.java:303)[spring-boot- 1.5.4.RELEASE.jar:1.5.4.RELEASE]在org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]在org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)[spring-b oot-1.5.4.RELEASE.jar:1.5.4.RELEASE] at com.ogl.JpaDemoApplication.main(JpaDemoApplication.java:15)[classes /:na]引起:org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有类型'javax.persistence.EntityManager'的限定bean可用:期望的单个匹配bean但在org.springframework中找到2:org.springframework.orm.jpa.SharedEntityManagerCreator#0,org.springframework.orm.jpa.SharedEntityManagerCreator#1 . org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency上的beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] (DefaultListableBeanFactory.java:1116)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)~ [ spring beans -4.3.9.RELEASE.jar:4.3.9.RELEASE]在org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:518)〜[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] org.springframework.context.annotation.CommonAnnotationBeanPostProcessor . org.springframework.context.annotation.CommonAnnotationBeanPostProcessor的getResource(CommonAnnotationBeanPostProcessor.java:496)~ [spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] $ ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:627)~ [spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]在org.springframework.beans.factory.annotation.InjectionMetadata $ InjectedElement.inject(InjectionMetadata.java:169)〜[spring-beans-4.3 . 9.RELEASE.jar:4.3.9.RELEASE]在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)〜[spring-beans-4.3.9.RELEASE.jar:4.3.9 .RELEASE]在org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnno) tationBeanPostProcessor.java:318)~ [spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE] ...省略了17个常用帧

Entity Manager 1

package com.ogl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(basePackages = "com.ogl.system", entityManagerFactoryRef = "companyEntityManagerFactory", transactionManagerRef = "companyTransactionManager")
public class SystemJpaConfig {

  private final Environment environment;

  @Autowired
  public SystemJpaConfig(Environment environment) {
    this.environment = environment;
  }

  @Bean("systemEntityManagerFactory")
  public LocalContainerEntityManagerFactoryBean systemEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPackagesToScan("com.ogl.system");
    entityManagerFactoryBean.setPersistenceUnitName("system");
    entityManagerFactoryBean.setDataSource(systemDataSource());

    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setDatabase(Database.POSTGRESQL);
    adapter.setShowSql(true);
    adapter.setGenerateDdl(false);

    entityManagerFactoryBean.setJpaVendorAdapter(adapter);

    return entityManagerFactoryBean;
  }

  @Bean
  DataSource systemDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getProperty("p4.datasource.driver"));
    dataSource.setUrl(environment.getProperty("p4.system.url"));
    dataSource.setUsername(environment.getProperty("p4.system.user"));
    dataSource.setPassword(environment.getProperty("p4.system.password"));

    return dataSource;
  }

  @Bean
  public PlatformTransactionManager systemTransactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory((systemEntityManagerFactory().getObject()));

    return transactionManager;
  }
}

Entity Manager 2

package com.ogl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;

import javax.sql.DataSource;

@Configuration
@EnableJpaRepositories(basePackages = "com.ogl.company", entityManagerFactoryRef = "companyEntityManagerFactory", transactionManagerRef = "companyTransactionManager")
public class CompanyJpaConfig {

  private final Environment environment;

  @Autowired
  public CompanyJpaConfig(Environment environment) {
    this.environment = environment;
  }

  @Primary
  @Bean("companyEntityManagerFactory")
  public LocalContainerEntityManagerFactoryBean companyEntityManagerFactory() {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setPackagesToScan("com.ogl.company");
    entityManagerFactoryBean.setPersistenceUnitName("company");
    entityManagerFactoryBean.setDataSource(companyDataSource());

    HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
    adapter.setDatabase(Database.POSTGRESQL);
    adapter.setShowSql(true);
    adapter.setGenerateDdl(false);

    entityManagerFactoryBean.setJpaVendorAdapter(adapter);

    return entityManagerFactoryBean;
  }

  @Bean
  DataSource companyDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getProperty("p4.datasource.driver"));
    dataSource.setUrl(environment.getProperty("p4.company.url"));
    dataSource.setUsername(environment.getProperty("p4.company.user"));
    dataSource.setPassword(environment.getProperty("p4.company.password"));

    return dataSource;
  }

  @Primary
  @Bean
  public PlatformTransactionManager companyTransactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory((companyEntityManagerFactory().getObject()));

    return transactionManager;
  }
}

Injection

package com.ogl;

import org.crygier.graphql.GraphQLExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
@ComponentScan
public class GraphQLJpaConfig {

  @PersistenceContext(unitName = "company")
  private EntityManager entityManager;

  @Bean
  public GraphQLExecutor graphQLExecutor() {
    return new GraphQLExecutor(entityManager);
  }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ogl</groupId>
    <artifactId>jpa-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>jpa-demo</name>
    <description>Demo project for JPA</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-java</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.crygier</groupId>
            <artifactId>graphql-jpa</artifactId>
            <version>0.3</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3 回答

  • 1

    您已定义了两个实体管理器 . 现在你必须告诉 Spring 天应注入哪一个 . 为此,您可以使用 @Qualifier 注释:

    @PersistenceContext(unitName = "company")
    @Qualifier(<Name of the entitimanager you want to use>)
    private EntityManager entityManager;
    
  • 3

    通过使用@Component标记我正在使用EntityManager注入的类来找到解决方案,然后将该类自动连接到使用GraphQLExecutor的类中:

    New class marked @Component

    package p4;
    
    import org.crygier.graphql.GraphQLExecutor;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.stereotype.Component;
    
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    @Component
    public class CompanyGraphQLComponent {
    
      @PersistenceContext(unitName = "company")
      private EntityManager entityManager;
    
      public GraphQLExecutor graphQLExecutor() {
        return new GraphQLExecutor(entityManager);
      }
    }
    

    Class auto-wiring CompanyGraphQLComponent

    package p4.rest.controllers;
    
    import core_services.persistence.CompanyContextHolder;
    import core_services.records.system.Company;
    import graphql.ExecutionResult;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import p4.CompanyGraphQLComponent;
    import p4.records.GraphQLQuery;
    
    @RestController
    public class GraphQLController {
      @Autowired
      private CompanyGraphQLComponent companyGraphQLComponent;
    
      @RequestMapping(value = "/graphql", consumes = MediaType.APPLICATION_JSON_VALUE)
      public ExecutionResult postJson(@RequestBody GraphQLQuery graphQLQuery) {
        return companyGraphQLComponent.graphQLExecutor().execute(graphQLQuery.getQuery(), graphQLQuery.getVariables());
      }
    }
    
  • 0

    您可以尝试在其中一个配置文件中通过entityManagerFactory和transactionManager提供注释@Primary吗?

相关问题