Spring Boot多模块项目多数据源

时间:2018-09-27 15:13:25

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

我正在尝试开发具有多数据源连接的多模块spring boot项目。我将此项目分为5个模块: -springboot-multiple-maven-modules:  1.域-> database2的模型  2. domain2-> database2的模型  3.持久性-> database1的持久性  4.持久性2->数据库2的持久性  5.网站->访问database1和database2

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

我已经以这种方式配置了两个数据源: -database1:

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

但是当我尝试使用Web模块中的存储库时:

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-multi-maven-modules \ web \ target \ classes \ rc \ web \ CocheController.class]:   通过构造函数参数0表示的不满足的依赖关系;   嵌套异常为   org.springframework.beans.factory.NoSuchBeanDefinitionException:否   类型为“ rc.persistence2.CocheRepository”的合格Bean可用:   期望至少有1个符合自动装配候选条件的bean。   依赖项注释:{} 2018-09-27 17:08:58.399 INFO 15272 --- [
  main] j.LocalContainerEntityManagerFactoryBean:关闭JPA   持久性单元'coche'的EntityManagerFactory 2018-09-27   17:08:58.400 INFO 15272 --- [main]   j.LocalContainerEntityManagerFactoryBean:关闭JPA   持久性单元'hotel'的EntityManagerFactory 2018-09-27   17:08:58.403 INFO 15272 --- [main]   o.apache.catalina.core.StandardService:正在停止服务[Tomcat]   2018-09-27 17:08:58.421 INFO 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   您的配置。

请帮助!

谢谢!

1 个答案:

答案 0 :(得分:0)

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

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

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