【问题标题】:Getting NoUniqueBeanDefinitionException when extends QueryDslRepositorySupport and multiple datasources扩展 QueryDslRepositorySupport 和多个数据源时获取 NoUniqueBeanDefinitionException
【发布时间】:2016-08-19 05:51:33
【问题描述】:

我需要使用多个数据库。 我正在使用 Spring Boot + Spring Data JPA, 所以我有两个配置类:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.rest.dao.first",
        entityManagerFactoryRef = "firstEntityManagerFactory", transactionManagerRef = "firstTransactionManager")
public static class DnbbJdbcConfig {

    @Primary
    @Bean
    @ConfigurationProperties(prefix="datasource.first")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Primary
    @Bean(name = "firstEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSource())
                .packages("com.rest.dao.first")
                .persistenceUnit("first")
                .build();
    }

    @Primary
    @Bean(name = "firstTransactionManager")
    PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactory(builder).getObject());
    }

}

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.rest.dao.second",
    entityManagerFactoryRef = "secondEntityManagerFactory", transactionManagerRef = "secondTransactionManager")
public static class SmsJdbcConfig {

    @Bean
    @ConfigurationProperties(prefix="datasource.second")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondEntityManagerFactory")
    @PersistenceContext(unitName = "second")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(dataSource())
                .packages("com.rest.dao.second")
                .persistenceUnit("second")
                .build();
    }

    @Bean(name = "secondTransactionManager")
    PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactory(builder).getObject());
    }
}

我猜没有错误和正确。 所以,当我使用默认存储库时,不会出错。 (例如 userRepository.findById() - 多数据源中没有错误)

但是,当我使用自定义存储库时,会发生错误。 (https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations)

自定义工具

public class FirstRepositoryImpl extends QueryDslRepositorySupport implements FirstCustomRepository {

public FirstRepositoryImpl() {
    super(First.class);
}

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

private QFirst first = QFirst.first;

@Override
public List<String> messages() {
    JPAQuery query = new JPAQuery(entityManager);
    return query.from(first).list(first.message);
}   
}

异常跟踪

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: firstEntityManagerFactory,secondEntityManagerFactory
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findDefaultEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:582) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findEntityManagerFactory(PersistenceAnnotationBeanPostProcessor.java:541) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.resolveEntityManager(PersistenceAnnotationBeanPostProcessor.java:707) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor$PersistenceElement.getResourceToInject(PersistenceAnnotationBeanPostProcessor.java:680) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:178) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:354) ~[spring-orm-4.2.3.RELEASE.jar:4.2.3.RELEASE]
... 45 common frames omitted

我是否配置错误?

我在我的 github 存储库中编写了示例代码.. https://github.com/okihouse/spring-boot-multiple-datasource-with-querydsl

【问题讨论】:

  • 您得到的异常是直截了当的。您定义了两个相同类型的bean。为避免此类异常,您可以使用 @Qualifier(secondEntityManagerFactory) (您希望此 bean 自动装配的位置)和 @Qualifier(firstEntityManagerFactory)
  • @Vaseph 我尝试@PersistenceUnit(name = "firstEntityManagerFactory", unitName = "first") @Qualifier("firstEntityManagerFactory") private EntityManagerFactory entityManagerFactory; 但仍然出错。
  • 你现在遇到了什么错误?
  • @Vaseph 这是同样的错误No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined: expected single matching bean but found 2: firstEntityManagerFactory,secondEntityManagerFactory 我运行调试,我在PersistenceAnnotationBeanPostProcessor.java:582 findDefaultEntityManagerFactory 中发现了一些代码sn-p 方法是默认使用EMF 当不存在unitName 时,对吗?为什么spring不执行protected EntityManagerFactory findNamedEntityManagerFactory(String unitName, String requestingBeanName)方法??

标签: spring hibernate spring-data-jpa querydsl multiple-databases


【解决方案1】:

自己解决了:

我查了QueryDslRepositorySupport.class,发现了。

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
    Assert.notNull(entityManager);
    this.querydsl = new Querydsl(entityManager, builder);
    this.entityManager = entityManager;
}

@PersistenceContext 没有“unitName” 所以,Spring 不能注入 EntityManager。

我创建QueryDslRepositorySupportWrapper.java 并手动注入 EntityManager。

而且它有效。

https://github.com/okihouse/spring-boot-multiple-datasource-with-querydsl

【讨论】:

  • 我最近遇到了同样的问题,这种方法也适用于我。
猜你喜欢
  • 2021-01-13
  • 2011-07-16
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 2020-08-03
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多