代码之家  ›  专栏  ›  技术社区  ›  Virat

在spring boot中连接到多个数据库

  •  4
  • Virat  · 技术社区  · 7 年前

    我需要连接到我的项目中的两个数据库。所以我创建了两个配置文件。

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories( basePackages = {"com.virat.webservices.datastore.v1.Repo" } )
    @EntityScan("com.virat.webservices.datastore.v1.Model")
    public class V1DBConfig {
    
    @Primary
    @Bean( name = "dataSource" )
    @ConfigurationProperties( prefix = "v1.datasource" )
    public DataSource dataSource()
    {
        return DataSourceBuilder.create().build();
    }
    
    @Primary
    @Bean( name = "entityManagerFactory" )
    public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder,
            @Qualifier( "dataSource" ) DataSource dataSource )
    {
        return builder.dataSource(dataSource).packages("com.virat.webservices.datastore.v1.Model")
                .persistenceUnit("db1").build();
    }
    
    @Primary
    @Bean( name = "transactionManager" )
    public PlatformTransactionManager transactionManager(
            @Qualifier( "entityManagerFactory" ) EntityManagerFactory entityManagerFactory )
    {
        return new JpaTransactionManager(entityManagerFactory);
    }
    }
    

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories( entityManagerFactoryRef = "v2EntityManagerFactory", transactionManagerRef = "v2TransactionManager",    basePackages = {
        "com.virat.datastore.repository" } )
    @EntityScan( "com.virat.datastore.model" )
    public class V2DBConfig {
    
    @Bean( name = "v2DataSource" )
    @ConfigurationProperties( prefix = "spring.datasource" )
    public DataSource dataSource()
    {
        return DataSourceBuilder.create().build();
    }
    
    @Bean( name = "v2EntityManagerFactory" )
    public LocalContainerEntityManagerFactoryBean barEntityManagerFactory( EntityManagerFactoryBuilder builder,
            @Qualifier( "v2DataSource" ) DataSource dataSource )
    {
        return builder.dataSource(dataSource).packages("com.virat.model")
                .persistenceUnit("db2").build();
    }
    
    @Bean( name = "v2TransactionManager" )
    public PlatformTransactionManager barTransactionManager(
            @Qualifier( "v2EntityManagerFactory" ) EntityManagerFactory barEntityManagerFactory )
    {
        return new JpaTransactionManager(barEntityManagerFactory);
    }
    }
    

    我配置了 application.properties 归档为,

    spring.datasource.type=com.zaxxer.hikari.HikariDataSource
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/db2?      useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=fal.   se&serverTimezone=UTC&useSSL=false
    spring.datasource.username=root
    spring.datasource.password=
    #spring.datasource.pool.size=20
    v1.datasource.driver-class-name=com.mysql.jdbc.Driver
    v1.datasource.url=jdbc:mysql://localhost:3306/db1?     useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=fal.   se&serverTimezone=UTC&useSSL=false
    v1.datasource.username=root
    v1.datasource.password=
    #v1.datasource.pool.size=20
    spring.jpa.properties.hibernate.id.new_generator_mappings=false
    v1.jpa.properties.hibernate.id.new_generator_mappings=false
    #spring.jpa.hibernate.ddl-auto=update
    spring.jpa.show-sql=true
    

    但当我运行应用程序时,引发了以下异常。

    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    Field entityManager in com.highpeak.tlp.webservices.services.impl.TaskServiceImpl required a single bean, but 2 were found:
        - org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
        - org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
    
    
    Action:
    
    Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
    
     org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter:42 - 
    
    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    Field entityManager in com.highpeak.tlp.webservices.services.impl.TaskServiceImpl required a single bean, but 2 were found:
        - org.springframework.orm.jpa.SharedEntityManagerCreator#0: defined by method 'createSharedEntityManager' in null
        - org.springframework.orm.jpa.SharedEntityManagerCreator#1: defined by method 'createSharedEntityManager' in null
    
    
    Action:
    
    Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
    
    Disconnected from the target VM, address: '127.0.0.1:56875', transport: 'socket'
    
    Process finished with exit code 1
    

    我无法确定是什么错误。我有两个模块。这个 repository entity 一个数据库的类在一个模块中,另一个数据库的类在另一个模块中。这是问题的根源吗?

    编辑

    我的 TaskServiceImpl.java

    package com.virat.webservices.services.impl;
    
    
    @Service
    public class TaskServiceImpl implements TaskService {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(TaskServiceImpl.class);
    
        @Autowired
        @PersistenceContext(unitName = "v2EntityManagerFactory")
        private EntityManager entityManager;
    
        @Value( "${file.base.path}" )
        private String basePath;
    
        @Value( "${application.domain}" )
        private String applicationDomain;
    
        @Value( "${application.protocol}" )
        private String applicationProtocol;
    
        @Value( "${server.port}" )
        private String serverPort;
    
        @Override
        @SuppressWarnings( "unchecked" )
        @Transactional( rollbackOn = DataException.class )
        public Integer doSomething( SomeObject someObject,
                UserAccessDetails userAccessDetails ) throws DataException
        {
            try
            {
                // Do input validations
                if( NullEmptyUtils.isNull(userAccessDetails) || NullEmptyUtils.isNull(someObject) )
                {
    
                    throw new DataException(GeneralConstants.EXCEPTION, GeneralConstants.NULL_INPUT_ERROR,
                            HttpStatus.BAD_REQUEST);
                }
    
                // Creates a native mysql query based on the contents of lawyerDiscoveryParamsBean
                /* Should be replaced with criteria API */
                String generatedQuery = DynamicQueryGenerator.getDynamicQuery(someObject, owner);
                LOGGER.info("Generated query: {}", generatedQuery);
                Query executableQuery = entityManager.createNativeQuery(generatedQuery, UserModel.class);
    
                List<UserModel> userModels = executableQuery.getResultList();
    
                if( userModels.isEmpty() )
                {
    
                    return 0;
                }
    
                return 1;
    
            }
            catch( DataException e )
            {
                LOGGER.error(GeneralConstants.ERROR, e);
                throw e;
            }
            catch( Exception e )
            {
                LOGGER.error(GeneralConstants.ERROR, e);
                throw new DataException(GeneralConstants.EXCEPTION, GeneralConstants.SOMETHING_WENT_WRONG,
                        HttpStatus.INTERNAL_SERVER_ERROR);
            }
        }
    
    }
    
    2 回复  |  直到 7 年前
        1
  •  1
  •   Naanavanalla    7 年前

    V1DBConfig.java ,注释 @EnableJpaRepository 实际上应该是这样,

    @EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = {
            "com.virat.webservices.datastore.v1.Repo" } )
    

    您已经在类中正确地完成了配置 V2DBConfig.java (看看 @启用计划 注释)。做同样的事 V1DBConfig.java .

    然后,在你的 TaskServiceImpl.java ,提供 PersistenceContext ,由回答 @Dan . 我希望这能有帮助。

        2
  •  2
  •   wilx    7 年前

    在你的 TaskServiceImpl 确保正确地注释了persistenceContext。

    例如:

    @PersistenceContext(unitName = "entityManagerFactory")
    private EntityManager em;