Spring Data中的多个数据源使用Spring Boot的JPA,

问题描述:

当我试图在Spring引导中使用两个数据库编写应用程序时,Spring Data JPA。它无法创建数据库,它的例外。下面是我的实现代码Spring Data中的多个数据源使用Spring Boot的JPA,

应用类

package com.icarat.eshiksha; 
@SpringBootApplication 
public class Application extends SpringBootServletInitializer { 
    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(Application.class); 
    } 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

application.xml文件

server.port=8080 
server.contextPath=/Eshiksha 

spring.datasource.driver-class-name=com.mysql.jdbc.Driver 
spring.datasource.url=jdbc:mysql://localhost:3306/db_shiksha2 
spring.datasource.username=root 
spring.datasource.password=***** 
spring.datasource.validation-query=select 1 

settings.datasource.driver-class-name=com.mysql.jdbc.Driver 
settings.datasource.url=jdbc:mysql://127.0.0.1:3306/db_shiksha_settings2 
settings.datasource.username=root 
settings.datasource.password=******* 
settings.datasource.validation-query=select 1 

ShikshaDbConfig类

package com.icarat.eshiksha.config; 
@Configuration 
@EnableTransactionManagement 
@EnableJpaRepositories(
     entityManagerFactoryRef = "shikshaEntityManagerFactory", 
     transactionManagerRef = "shikshaTransactionManager", 
     basePackages = { "com.icarat.eshiksha.repository" }) 
public class ShikshaDbConfig { 


    @Autowired 
    JpaVendorAdapter jpaVendorAdapter; 

    @Autowired 
    DataSource dataSource; 

    @Bean(name = "shikshaManager") 
    public EntityManager shikshaManager() { 
     return shikshaEntityManagerFactory().createEntityManager(); 
    } 

    @Primary 
    @Bean(name = "shikshaEntityManagerFactory") 
    public EntityManagerFactory shikshaEntityManagerFactory() { 

      Properties properties = new Properties(); 
      properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); 
      properties.setProperty("hibernate.hbm2ddl.auto","update"); 
      properties.setProperty("hibernate.show_sql", "false"); 

     LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
     emf.setDataSource(dataSource); 
     emf.setJpaVendorAdapter(jpaVendorAdapter); 
     emf.setJpaProperties(properties); 
     emf.setPackagesToScan("com.icarat.eshiksha.database.entities"); 
     emf.setPersistenceUnitName("default"); // <- giving 'default' as name 
     emf.afterPropertiesSet(); 
     return emf.getObject(); 
    } 

    @Bean(name = "shikshaTransactionManager") 
    public PlatformTransactionManager shikshaTransactionManager() { 
     JpaTransactionManager tm = new JpaTransactionManager(); 
     tm.setEntityManagerFactory(shikshaEntityManagerFactory()); 
     return tm; 
    } 
} 

ShikshaSettingsDbConfig类

@Configuration 
@EnableTransactionManagement 
@EnableJpaRepositories(
     entityManagerFactoryRef = "settingEntityManagerFactory", 
     transactionManagerRef = "shikshaSettingsTransactionManager", 
     basePackages = { "com.icarat.eshiksha.settings.repository" }) 
public class ShikshaSettingsDbConfig { 

    @Autowired 
     JpaVendorAdapter jpaVendorAdapter; 

     @Value("${settings.datasource.url}") 
     private String databaseUrl; 

     @Value("${settings.datasource.username}") 
     private String username; 

     @Value("${settings.datasource.password}") 
     private String password; 

     @Value("${settings.datasource.driver-class-name}") 
     private String driverClassName; 



     public DataSource dataSource() { 
      DriverManagerDataSource dataSource = new DriverManagerDataSource(databaseUrl, username, password); 
      dataSource.setDriverClassName(driverClassName); 
      return dataSource; 
     } 

     @Bean(name = "settingEntityManager") 
     public EntityManager settingEntityManager() { 
      return settingEntityManagerFactory().createEntityManager(); 
     } 

     @Bean(name = "settingEntityManagerFactory") 
     public EntityManagerFactory settingEntityManagerFactory() { 
      Properties properties = new Properties(); 
       properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); 
       properties.setProperty("hibernate.hbm2ddl.auto","update"); 
       properties.setProperty("hibernate.show_sql", "false"); 
      properties.setProperty("hibernate.cache.use_second_level_cache", "true"); 
      properties.setProperty("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.EhCacheRegionFactory"); 

      LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean(); 
      emf.setDataSource(dataSource()); 
      emf.setJpaVendorAdapter(jpaVendorAdapter); 
      emf.setPackagesToScan("com.icarat.eshiksha.settings.database.entites"); // <- package for entities 
      emf.setPersistenceUnitName("settingPersistenceUnit"); 
      emf.setJpaProperties(properties); 
      emf.afterPropertiesSet(); 
      return emf.getObject(); 
     } 

     @Bean(name = "settingsTransactionManager") 
     public PlatformTransactionManager settingsTransactionManager() { 
      return new JpaTransactionManager(settingEntityManagerFactory()); 
     }  
} 

组织类

@Entity 
@Table(name = "Organization") 
public class Organization { 

    @Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
    @Column(name="orgId") 
    private String orgId; 

    @Column(name="orgName", unique=true) 
    private String orgName; 

    @Column(name="orgAddress") 
    private String orgAddress; 

    @Column(name="pincode") 
    private String pincode; 


    @Column(name="boardOfEducation") 
    private String boardOfEducation; 

    @Column(name="recognizedBy") 
    private String recognizedBy; 

    @Column(name="affiliationNumber") 
    private String affiliationNumber; 


    @Column(name="faxNumber") 
    private String faxNumber; 


    @Column(name = "isActive") 
    private boolean isActive = true; 

    @OneToOne 
    private OrganizationAdmin admin; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy="org", cascade=CascadeType.REMOVE) 
    private List<Branch> branches =new ArrayList<Branch>(); 
//getter //setter 
} 

OrganizationDAOImpl类

package com.icarat.eshiksha.dao.impl; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.dao.DataIntegrityViolationException; 
import org.springframework.stereotype.Service; 
import com.icarat.eshiksha.dao.OrganizationDAO; 
import com.icarat.eshiksha.database.entities.Organization; 
import com.icarat.eshiksha.dto.AddOrgRequestDTO; 
import com.icarat.eshiksha.repository.OrganizationRepository; 
import com.icarat.eshiksha.util.StringConstants; 

@Service 
public class OrganizationDAOImpl implements OrganizationDAO { 

    @Autowired 
    private OrganizationRepository organizationRepository; 

    @Override 
    public String addOrganization(AddOrgRequestDTO request) { 
     Organization org = createHomeEntity(request); 
     try {  
      organizationRepository.save(org);  
      return StringConstants.SUCCESS; 
     }catch(DataIntegrityViolationException e) {  
      e.printStackTrace();     
      return null; 
     } catch(Exception e) { 
      e.printStackTrace();   
      return null; 
     } 
     } 

    private Organization createHomeEntity(final AddOrgRequestDTO request) { 
     Organization home = new Organization(); 
     home.setOrgName(request.getOrgName()); 
     home.setOrgAddress(request.getAddress()); 
     home.setPincode(request.getPincode()); 
     if(request.getFaxNumber()!=null){ 
     home.setFaxNumber(request.getFaxNumber()); 
     } 
     if(request.getBoardOfEducation()!=null){ 
      home.setBoardOfEducation(request.getBoardOfEducation()); 
      } 
      if(request.getRecognizedBy()!=null){ 
       home.setRecognizedBy(request.getRecognizedBy()); 
      } 
      if(request.getAffiliationNumber()!=null){ 
       home.setAffiliationNumber(request.getAffiliationNumber()); 
      } 
     return home; 
    } 

OrganizationRepository类

package com.icarat.eshiksha.repository; 
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 
import com.icarat.eshiksha.database.entities.Organization; 
@Repository 
public interface OrganizationRepository extends JpaRepository<Organization, String>{ 

} 

抛出的异常被

2017-05-28 16:08:16.061 WARN 4424 --- [   main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organizationDAOImpl': Unsatisfied dependency expressed through field 'organizationRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'organizationRepository': Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingEntityManagerFactory' defined in class path resource [com/icarat/eshiksha/config/ShikshaSettingsDbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
2017-05-28 16:08:16.070 INFO 4424 --- [   main] utoConfigurationReportLoggingInitializer : 

Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled. 
2017-05-28 16:08:16.075 ERROR 4424 --- [   main] o.s.boot.SpringApplication    : Application startup failed 

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'organizationDAOImpl': Unsatisfied dependency expressed through field 'organizationRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'organizationRepository': Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingEntityManagerFactory' defined in class path resource [com/icarat/eshiksha/config/ShikshaSettingsDbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) [spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:372) [spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1187) [spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1176) [spring-boot-1.4.4.RELEASE.jar:1.4.4.RELEASE] 
    at com.icarat.eshiksha.Application.main(Application.java:38) [classes/:na] 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'organizationRepository': Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingEntityManagerFactory' defined in class path resource [com/icarat/eshiksha/config/ShikshaSettingsDbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1531) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1276) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    ... 19 common frames omitted 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingEntityManagerFactory' defined in class path resource [com/icarat/eshiksha/config/ShikshaSettingsDbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    ... 32 common frames omitted 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'settingEntityManagerFactory' defined in class path resource [com/icarat/eshiksha/config/ShikshaSettingsDbConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1067) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:519) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java:508) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.getBeansOfType(AbstractApplicationContext.java:1189) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestors(BeanFactoryUtils.java:261) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.getMetamodels(JpaMetamodelMappingContextFactoryBean.java:85) ~[spring-data-jpa-1.10.7.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:56) ~[spring-data-jpa-1.10.7.RELEASE.jar:na] 
    at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:26) ~[spring-data-jpa-1.10.7.RELEASE.jar:na] 
    at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    ... 39 common frames omitted 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'settingEntityManagerFactory' threw exception; nested exception is java.lang.AbstractMethodError 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    ... 57 common frames omitted 
Caused by: java.lang.AbstractMethodError: null 
    at org.hibernate.internal.CacheImpl.<init>(CacheImpl.java:49) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:28) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.engine.spi.CacheInitiator.initiateService(CacheInitiator.java:20) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.initiateService(SessionFactoryServiceRegistryImpl.java:49) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:254) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:228) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:207) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:68) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:244) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444) ~[hibernate-core-5.0.11.Final.jar:5.0.11.Final] 
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879) ~[hibernate-entitymanager-5.0.11.Final.jar:5.0.11.Final] 
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362) ~[spring-orm-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at com.icarat.eshiksha.config.ShikshaSettingsDbConfig.settingEntityManagerFactory(ShikshaSettingsDbConfig.java:71) ~[classes/:na] 
    at com.icarat.eshiksha.config.ShikshaSettingsDbConfig$$EnhancerBySpringCGLIB$$1d6ef92.CGLIB$settingEntityManagerFactory$0(<generated>) ~[classes/:na] 
    at com.icarat.eshiksha.config.ShikshaSettingsDbConfig$$EnhancerBySpringCGLIB$$1d6ef92$$FastClassBySpringCGLIB$$b22a78eb.invoke(<generated>) ~[classes/:na] 
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356) ~[spring-context-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    at com.icarat.eshiksha.config.ShikshaSettingsDbConfig$$EnhancerBySpringCGLIB$$1d6ef92.settingEntityManagerFactory(<generated>) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_73] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_73] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_73] 
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_73] 
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.3.6.RELEASE.jar:4.3.6.RELEASE] 
    ... 58 common frames omitted 

我该如何解决这个问题。请帮忙找出来。谢谢

+1

[Spring Boot配置和使用两个数据源]的可能重复(https://stackoverflow.com/questions/30337582/spring-boot-configure-and-use-two-datasources) –

我创建了一个工作POC here。说明可在README.md中找到。这个解决方案使用Gradle构建,并使用Docker来保存两个MySQL实例和一个SpringBoot应用程序公开一个REST端点。

您实现几点:

1.使用独特的bean的名字

您定义对应的两个数据源两种配置。你需要用@Bean("name")来命名每个bean,并用@Qualifier("name")的名字注入它们。

另外其中一个配置需要使用其注释为@Primary的其他bean将不起作用,请不要问我为什么。如果您有多个相同类型的bean按类型注入而没有进一步的限定,则正常情况下会收到错误,但即使注入限定为@Qualifier("name"),其中"name"是唯一的,也会显示错误。

例如配置的一个可能看起来像:

​​。

package my.java.spring.jpa.multi.repositories.config; 

import my.java.spring.jpa.multi.models.Organization; 
import my.java.spring.jpa.multi.repositories.source1.Source1OrganizationRepositoryImpl; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Primary; 
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 
import org.springframework.orm.jpa.JpaTransactionManager; 
import org.springframework.orm.jpa.JpaVendorAdapter; 
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
import org.springframework.orm.jpa.vendor.HibernateJpaDialect; 
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; 
import org.springframework.transaction.PlatformTransactionManager; 

import javax.persistence.EntityManagerFactory; 
import javax.sql.DataSource; 

/** 
* Repository configuration. 
* @EnableJpaRepositories to enable JPA automatic repositories. 
*/ 
@Configuration 
@EnableJpaRepositories(
     basePackageClasses = { Source1OrganizationRepositoryImpl.class }, 
     entityManagerFactoryRef = MySqlSource1Config.EntityManagerFactoryBeanName, 
     transactionManagerRef = MySqlSource1Config.TransactionManagerBeanName 
) 
public class MySqlSource1Config { 

    public static final String PrefixName = "source1"; 
    public static final String DataSourceBeanName = PrefixName + ".data-source"; 
    public static final String JpaVendorAdapterBeanName = PrefixName + "jpa-vendor-adapter"; 
    public static final String EntityManagerFactoryBeanName = PrefixName + ".entity-manager-factory"; 
    public static final String TransactionManagerBeanName = PrefixName + ".transaction-manager"; 
    public static final String RepositoryBeanName = PrefixName + ".repository"; 

    @Bean(TransactionManagerBeanName) 
    @Primary 
    public PlatformTransactionManager transactionManager(
      @Qualifier(EntityManagerFactoryBeanName) EntityManagerFactory entityManagerFactory) { 
     return new JpaTransactionManager(entityManagerFactory); 
    } 

    @Bean(EntityManagerFactoryBeanName) 
    @Primary 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(
      @Qualifier(DataSourceBeanName) DataSource dataSource, 
      @Qualifier(JpaVendorAdapterBeanName) JpaVendorAdapter vendorAdapter) { 

     LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     entityManagerFactoryBean.setDataSource(dataSource); 
     entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter); 
     entityManagerFactoryBean.setJpaDialect(new HibernateJpaDialect()); 
     entityManagerFactoryBean.setPackagesToScan(Organization.class.getPackage().getName()); 
     entityManagerFactoryBean.setPersistenceUnitName("mysqlsource1"); 
     entityManagerFactoryBean.afterPropertiesSet(); 

     return entityManagerFactoryBean; 
    } 

    @Bean(JpaVendorAdapterBeanName) 
    @Primary 
    @ConfigurationProperties(prefix = "source1.mysql.jpa") 
    public JpaVendorAdapter jpaVendorAdapter() { 
     return new HibernateJpaVendorAdapter(); 
    } 

    @Bean(DataSourceBeanName) 
    @Primary 
    @ConfigurationProperties(prefix = "source1.mysql.datasource") 
    public DataSource dataSource() { 
     return DataSourceBuilder.create().build(); 
    } 
} 

2。通过bean的名字注入豆

由于多个bean定义被发现同一类型,你应该@Qualifier()注入他们的名字豆:

@Bean(TransactionManagerBeanName) 
@Primary 
public PlatformTransactionManager transactionManager(
     @Qualifier(EntityManagerFactoryBeanName) EntityManagerFactory entityManagerFactory) { 
    return new JpaTransactionManager(entityManagerFactory); 
} 

相比之下,以下是从您的代码中提取:

@Bean(name = "shikshaTransactionManager") 
public PlatformTransactionManager shikshaTransactionManager() { 
    JpaTransactionManager tm = new JpaTransactionManager(); 
    tm.setEntityManagerFactory(shikshaEntityManagerFactory()); 
    return tm; 
} 

这是不正常的,因为shikshaEntityManagerFactory()将创建EntityManagerFactory的新实例,而不是注入现有的bean的。

3.无需显式定义EntityManager当你有EntityManagerFactory

是从你的问题中提取的以下内容:

@Bean(name = "shikshaManager") 
public EntityManager shikshaManager() { 
    return shikshaEntityManagerFactory().createEntityManager(); 
} 

@Primary 
@Bean(name = "shikshaEntityManagerFactory") 
public EntityManagerFactory shikshaEntityManagerFactory() { ... } 

的一点是,这两个定义,还有一点就是,如果您仍然需要EntityManager那么您应该注入EntityManagerFactory bean,而不是执行方法调用shikshaEntityManagerFactory(),该方法会生成另一个EntityManagerFactory实例。

4.简化配置

可以使用@ConfigurationProperties而不是@Value多个配置属性加载到豆状:

@Bean(JpaVendorAdapterBeanName) 
    @Primary 
    @ConfigurationProperties(prefix = "source1.mysql.jpa") 
    public JpaVendorAdapter jpaVendorAdapter() { 
     return new HibernateJpaVendorAdapter(); 
    } 

    @Bean(DataSourceBeanName) 
    @Primary 
    @ConfigurationProperties(prefix = "source1.mysql.datasource") 
    public DataSource dataSource() { 
     return DataSourceBuilder.create().build(); 
    } 

然后是application.yml两个数据源的样子:

source1: 
    mysql: 
    jpa: 
     show-sql: true 
     generate-ddl: true 
     database: MYSQL 
    datasource: 
     platform: postgres 
     url: jdbc:mysql://localhost:3307/test1 
     username: myuser1 
     password: mypass1 
     driverClassName: com.mysql.cj.jdbc.Driver 
source2: 
    mysql: 
    jpa: 
     show-sql: true 
     generate-ddl: true 
     database: MYSQL 
    datasource: 
     platform: postgres 
     url: jdbc:mysql://localhost:3308/test2 
     username: myuser2 
     password: mypass2 
     driverClassName: com.mysql.cj.jdbc.Driver 

请注意,jpa被加载到JpaVendorAdapterdatasourceDataSource

5.保持数据源库分离

如果需要使用相同的实体和资源库和多个数据源,那么你可以保持一个通用的接口OrganizationRepository,并有单独的接口Source1OrganizationRepository和IMPL Source1OrganizationRepositoryImpl。另一方面,如果您有多个数据源未使用的实体和存储库(例如:由source1管理的组织和由source2管理的用户),则会有不同的包由不同的源管理,但不包含需要一个通用接口。

这允许以命名库豆等:为了从其他数据源储存库来区分

@Repository(MySqlSource1Config.RepositoryBeanName) 
public interface Source1OrganizationRepository extends OrganizationRepository { 
} 

这些被配置为,像您已经使用了他们在你的配置(注意basePackageClasses):

@Configuration 
@EnableJpaRepositories(
     basePackageClasses = { Source1OrganizationRepositoryImpl.class }, 
     entityManagerFactoryRef = MySqlSource1Config.EntityManagerFactoryBeanName, 
     transactionManagerRef = MySqlSource1Config.TransactionManagerBeanName 
) 
public class MySqlSource1Config { ... } 

然后这些存储库还可以被注入,到控制器,服务,或任何其他组件,如:

@RestController 
@RequestMapping("/v1/organization") 
public class OrganizationController { 

    private final OrganizationRepository organizationRepositoryFromSource1; 
    private final OrganizationRepository organizationRepositoryFromSource2; 

    @Autowired 
    public OrganizationController(
      @Qualifier(MySqlSource1Config.RepositoryBeanName) OrganizationRepository organizationRepositoryFromSource1, 
      @Qualifier(MySqlSource2Config.RepositoryBeanName) OrganizationRepository organizationRepositoryFromSource2) { 

     this.organizationRepositoryFromSource1 = organizationRepositoryFromSource1; 
     this.organizationRepositoryFromSource2 = organizationRepositoryFromSource2; 
    } 

... 
} 

相同的实体可以与多个数据源被使用并且由EntityManager被加载,并且可以在内部EntityManagerFactory进行配置:

@Bean(EntityManagerFactoryBeanName) 
@Primary 
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
     @Qualifier(DataSourceBeanName) DataSource dataSource, 
     @Qualifier(JpaVendorAdapterBeanName) JpaVendorAdapter vendorAdapter) { 

... 
entityManagerFactoryBean.setPackagesToScan(Organization.class.getPackage().getName()); 
... 

} 

注:application.ymlapplication-docker.yml我用source1.mysql.jpa.generate-ddl: true。这意味着将在MySQL数据库中自动创建与EntityManager找到的实体对应的表和模式。如果您通过其他方式管理数据库架构(如创建脚本并使用FlyWayLiquidbase进行迁移),那么您可能需要将该选项转换为false以采用自己的流程。