0

Мне нужно использовать несколько баз данных. Я использую Spring загрузочную + Spring Data JPA, поэтому у меня есть два класса конфигурации:Получение NoUniqueBeanDefinitionException при расширении QueryDslRepositorySupport и нескольких источников данных

@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); 
} 
} 

ExceptionTrace

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

+1

Исключением, которое вы получаете, является прямым. Вы определяете два компонента, которые являются одинаковыми. чтобы избежать такого исключения, вы можете использовать @Qualifier (secondEntityManagerFactory) (где вы хотите, чтобы этот компонент был автообновлен) и @Qualifier (firstEntityManagerFactory) – Vaseph

+0

@ Vaseph Я пытаюсь '@PersistenceUnit (name =" firstEntityManagerFactory ", unitName =" first ") \t @Qualifier ("firstEntityManagerFactory") \t private EntityManagerFactory entityManagerFactory; 'но все еще ошибка. – OKIHOUSE

+0

какая ошибка у вас появилась? – Vaseph

ответ

2

решаемые себя:

Я проверить QueryDslRepositorySupport.class и выяснили.

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

@PersistenceContext не "UnitName" Итак, весна не может придать EntityManager.

Я создаю QueryDslRepositorySupportWrapper.java и вводим EntityManager вручную.

И это работает.

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

+0

Недавно я столкнулся с той же проблемой, и этот подход сработал и для меня. –