我需要在项目中连接到两个数据库。因此,我创建了两个配置文件。
@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文件配置为
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
我无法识别出什么错误。我有两个模块。一个数据库的repositoryand entity类在一个模块中,另一个数据库的类在另一个模块中。这引起问题吗?
repository
entity
编辑
我的 TaskServiceImpl.java
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); } } }
在中V1DBConfig.java,注释@EnableJpaRepository实际上应该是这样的,
V1DBConfig.java
@EnableJpaRepository
@EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactory", transactionManagerRef = "transactionManager", basePackages = { "com.virat.webservices.datastore.v1.Repo" } )
您已经在类中完成了配置V2DBConfig.java(请看@EnableJpaRepository注释)。在中做同样的事情V1DBConfig.java。
V2DBConfig.java