【问题标题】:Spring boot Multi-module project multi-datasourceSpring boot 多模块项目多数据源
【发布时间】:2019-03-03 13:22:01
【问题描述】:

我正在尝试开发一个具有多数据源连接的多模块 Spring Boot 项目。我将这个项目分为 5 个模块: -springboot-multiple-maven-modules: 1. 域 -> database2 的模型 2. domain2 -> database2的模型 3.持久化->database1的持久化 4. persistence2 -> database2的持久化 5. web -> 访问database1和database2

您可以在以下链接下载代码: GitHub Project

我以这种方式配置了两个数据源: - 数据库1:

package rc.persistence;

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.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "hotelEntityManagerFactory", transactionManagerRef = "hotelTransactionManager", basePackages = {
        "rc.repository" }) //Mirar si se puede sustituir por rc.domain o rc.repository
public class HotelDbConfig {

    @Autowired
    private Environment env;

    @Bean(name = "hotelDataSource")
    @ConfigurationProperties(prefix = "hoteles.datasource")
    public DataSource customDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("hoteles.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("hoteles.datasource.url"));
        dataSource.setUsername(env.getProperty("hoteles.datasource.username"));
        dataSource.setPassword(env.getProperty("hoteles.datasource.password"));
        return dataSource;
    }

    @Bean(name = "hotelEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("hotelDataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("rc.domain")
                .persistenceUnit("hotel").build();
    }

    @Bean(name = "hotelTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("hotelEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}
  • 数据库2:
package rc.persistence2;
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.context.properties.ConfigurationProperties;
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 = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
        "rc.repository2" }) 

public class CocheDbConfig {

    @Autowired
    private Environment env;

    @Primary
    @Bean(name = "cocheDataSource")
    @ConfigurationProperties(prefix = "coches.datasource")
    public DataSource customDataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("coches.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("coches.datasource.url"));
        dataSource.setUsername(env.getProperty("coches.datasource.username"));
        dataSource.setPassword(env.getProperty("coches.datasource.password"));
        return dataSource;
    }

    @Primary
    @Bean(name = "cocheEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder,
            @Qualifier("cocheDataSource") DataSource dataSource) {
        return builder.dataSource(dataSource).packages("rc.domain2")
                .persistenceUnit("coche").build();
    }

    @Primary
    @Bean(name = "cocheTransactionManager")
    public PlatformTransactionManager transactionManager(
            @Qualifier("cocheEntityManagerFactory") EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

但是当我尝试使用来自网络模块的存储库时:

package rc.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import rc.domain2.Coche;
import rc.persistence2.CocheRepository;

@RestController
public class CocheController {

    @Autowired
    private CocheRepository cocheRepository;

    public CocheController(CocheRepository cocheRepository) {
        this.cocheRepository = cocheRepository;
    }

    @GetMapping(value = "/coches")
    public List<Coche> getCoches() {
        List<Coche> hotels = this.cocheRepository.findAll();
        return hotels;
    }
}

它显示以下错误:

我尝试了不同的可能性,但结果总是相同:

2018-09-27 17:08:58.399 警告 15272 --- [主要] ConfigServletWebServerApplicationContext:遇到异常 在上下文初始化期间 - 取消刷新尝试: org.springframework.beans.factory.UnsatisfiedDependencyException: 创建文件中定义的名称为“cocheController”的 bean 时出错 [C:\springboot-multiple-maven-modules\web\target\classes\rc\web\CocheController.class]: 通过构造函数参数 0 表示的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: 否 'rc.persistence2.CocheRepository' 类型的合格 bean 可用: 预计至少有 1 个 bean 有资格作为 autowire 候选者。 依赖注释:{} 2018-09-27 17:08:58.399 INFO 15272 --- [
main] j.LocalContainerEntityManagerFactoryBean : 关闭 JPA EntityManagerFactory 用于持久性单元'coche' 2018-09-27 17:08:58.400 信息 15272 --- [主要] j.LocalContainerEntityManagerFactoryBean :关闭 JPA EntityManagerFactory 用于持久化单元“酒店” 2018-09-27 17:08:58.403 信息 15272 --- [主要] o.apache.catalina.core.StandardService :停止服务 [Tomcat] 2018-09-27 17:08:58.421 信息 15272 --- [主要] ConditionEvaluationReportLoggingListener:

启动 ApplicationContext 时出错。显示条件报告 在启用“调试”的情况下重新运行您的应用程序。 2018-09-27 17:08:58.670 错误 15272 --- [主要] o.s.b.d.LoggingFailureAnalysisReporter:

***************************应用程序启动失败


说明:

rc.web.CocheController 中构造函数的参数 0 需要一个 bean 找不到类型“rc.persistence2.CocheRepository”。

行动:

考虑定义一个 'rc.persistence2.CocheRepository' 类型的 bean 你的配置。

请帮忙!!

提前致谢!

【问题讨论】:

  • 你有一个类 rc.persistence2.CocheRepository 吗?您尚未粘贴上面此类的代码。您是否在该类中正确配置了 bean?
  • 请从CocheController 类中删除@Autowired。如果一个 bean 有一个构造函数,你可以省略@Autowired,更多细节参见here
  • 看来失败的原因是CocheControllerCocheRepository这两个类在不同的模块中。

标签: spring-boot spring-data-jpa multi-model-database


【解决方案1】:

您在数据源配置中遇到错误。您的 CocheDbConfig 数据源正在扫描基于包“rc.repository2”以查找 Repository 类,因此它无法在您的控制器中找到 bean 'rc.persistence2.CocheRepository'。

您应该像这样更改 database2 数据源中的基础包

@EnableJpaRepositories(entityManagerFactoryRef = "cocheEntityManagerFactory", transactionManagerRef = "cocheTransactionManager", basePackages = {
        "rc.persistence2" })

【讨论】:

    猜你喜欢
    • 2020-11-12
    • 2018-10-07
    • 2015-10-10
    • 1970-01-01
    • 2014-06-02
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    相关资源
    最近更新 更多