Spring Boot 多个数据库:没有 EntityManagerFactoryBuilder 类型的合格 bean [英] Spring Boot Multiple Databse : No qualifying bean of type EntityManagerFactoryBuilder

查看:85
本文介绍了Spring Boot 多个数据库:没有 EntityManagerFactoryBuilder 类型的合格 bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的 Spring Boot 应用程序中有两个数据库,称为源和目标.这是那些的配置

We have two databases in our Spring Boot Application called source and target. Here is the configuration for those

源配置

package com.alex.myapp.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "sourceManagerFactory",
        transactionManagerRef = "sourceTransactionManager",
        basePackages = {"com.alex.myapp.source.repository"}
)
public class SourceDbConfiguration {

    @Autowired
    private Environment env;

    @Primary
    @Bean(name = "sourceManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    sourceManagerFactory(EntityManagerFactoryBuilder builder) {
        LocalContainerEntityManagerFactoryBean em = builder
                .dataSource(sourceDataSource())
                .packages("com.alex.myapp.source.entity")
                .persistenceUnit("source")
                .build();
        return em;
    }

    @Primary
    @Bean
    public DataSource sourceDataSource() {
        DriverManagerDataSource dataSource
                = new DriverManagerDataSource();
        dataSource.setDriverClassName(
                env.getProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("spring.datasource.url"));
        dataSource.setUsername(env.getProperty("spring.datasource.username"));
        dataSource.setPassword(env.getProperty("spring.datasource.password"));

        return dataSource;
    }

    @Primary
    @Bean(name = "sourceTransactionManager")
    public PlatformTransactionManager sourceTransactionManager(
            @Qualifier("sourceManagerFactory") EntityManagerFactory
                    sourceManagerFactory
    ) {
        return new JpaTransactionManager(sourceManagerFactory);
    }
}

目标配置

package com.alex.myapp.config;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "targetManagerFactory",
        transactionManagerRef = "targetTransactionManager",
        basePackages = {"com.alex.myapp.target.repository"}
)
public class TargetDbConfiguration {

    @Autowired
    private Environment env;

    @Primary
    @Bean(name = "targetManagerFactory")
    public LocalContainerEntityManagerFactoryBean
    targetManagerFactory(EntityManagerFactoryBuilder builder) {
        LocalContainerEntityManagerFactoryBean em = builder
                .dataSource(targetDataSource())
                .packages("com.alex.myapp.target.entity")
                .persistenceUnit("target")
                .build();
        return em;
    }

    @Primary
    @Bean
    public DataSource targetDataSource() {
        DriverManagerDataSource dataSource
                = new DriverManagerDataSource();
        dataSource.setDriverClassName(
                env.getProperty("target.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("target.datasource.url"));
        dataSource.setUsername(env.getProperty("target.datasource.username"));
        dataSource.setPassword(env.getProperty("target.datasource.password"));

        return dataSource;
    }

    @Bean(name = "targetTransactionManager")
    public PlatformTransactionManager targetTransactionManager(
            @Qualifier("targetManagerFactory") EntityManagerFactory
                    targetManagerFactory) {
        return new JpaTransactionManager(targetManagerFactory);
    }
}

当我尝试启动服务器时,它会抛出下面提到的错误

When I try to start server it throws below mentioned error

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-09-19 13:30:53 - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sourceManagerFactory' defined in class path resource [com/alex/myapp/config/SourceDbConfiguration.class]: Unsatisfied dependency expressed through method 'sourceManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:732)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:474)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1247)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1096)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:535)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1089)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:859)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)

如果我注释掉目标配置的类级别注释,一切正常.似乎两个数据库配置相互冲突.

Jut in case if I comment out target configuration's class level annotation everything works fine. It seems both Database Configurations are conflicting with each other.

推荐答案

@Primary 必须完全用于所需类型中的一个 bean.

@Primary must be used exactly on one bean among the required types.

@Primary 中提取java文档

表示当多个候选者有资格自动装配单值依赖项时,应该优先考虑一个 bean.如果候选中恰好存在一个主要"bean,它将是自动装配的值.

Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.

这篇关于Spring Boot 多个数据库:没有 EntityManagerFactoryBuilder 类型的合格 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆