当我尝试在Spring启动时使用两个数据库编写一个应用程序Spring Data 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 class
@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 class
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
我该如何解决这个问题。请帮忙找出来。谢谢
答案 0 :(得分:0)
我创建了一个有效的POC here。 README.md中提供了相关说明。此解决方案使用Gradle构建,并使用Docker保留两个MySQL实例和一个暴露REST端点的SpringBoot应用程序。
有关实施的一些要点:
<强> 1。使用唯一的bean名称
您定义了与两个数据源对应的两个配置。您需要使用@Bean("name")
为每个bean命名,并使用@Qualifier("name")
按名称注入它们。
其中一个配置需要使用其他@Primary
注释的bean不起作用,不要问我为什么。如果您有多个相同类型的bean在没有任何进一步限定的情况下注入的情况下接收错误是正常的,但即使注入符合@Qualifier("name")
,其中"name"
是唯一的,也会出现错误。< / p>
例如,其中一个配置可能如下所示:
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
因为找到了相同类型的多个bean定义,所以应该使用@Qualifier()
的名称注入bean:
@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中,如:
@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
已加载到JpaVendorAdapter
和datasource
加载到DataSource
。
<强> 5。保持数据源存储库分开
如果您需要使用具有多个数据源的相同实体和存储库,那么您可以保留一个公共接口OrganizationRepository
,并具有单独的接口Source1OrganizationRepository
和IMPL Source1OrganizationRepositoryImpl
。
另一方面,如果您有多个数据源未使用的实体和存储库(例如:由source1管理的组织和由source2管理的用户),那么将有不同的源管理不同的包,但不需要对于一个通用的界面。
这允许将存储库bean命名为:
@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.yml
和application-docker.yml
我使用了source1.mysql.jpa.generate-ddl: true
。这意味着将在MySQL数据库中自动创建与EntityManager
找到的实体对应的表和模式。如果您通过其他方式管理数据库架构,例如创建脚本并使用FlyWay
或Liquidbase
迁移它们,那么您可能希望将该选项设置为false
以采用您自己的流程