gpt4 book ai didi

java - 使用 Hibernate 定义两个数据源——一个关系型数据源和一个 NoSQL 型数据源

转载 作者:行者123 更新时间:2023-11-30 10:02:49 25 4
gpt4 key购买 nike

在我们的项目中,我们有两个数据库:一个关系数据库(ms sql server)和一个 NoSQL(MongoDB)。当我启动项目时出现此错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'appServiceRepository': Cannot create inner bean '(inner bean)#2f5abe7' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2f5abe7': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in eu.voiceweb.config.DatabaseConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'entityManagerFactory' threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: Rule, for columns: [org.hibernate.mapping.Column(filledSlots)]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:327) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:131) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1681) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1433) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:277) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1248) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1168) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 141 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#2f5abe7': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in eu.voiceweb.config.DatabaseConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'entityManagerFactory' threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: Rule, for columns: [org.hibernate.mapping.Column(filledSlots)]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:662) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:479) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:312) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 154 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in eu.voiceweb.config.DatabaseConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.persistence.EntityManagerFactory]: Factory method 'entityManagerFactory' threw exception; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.List, at table: Rule, for columns: [org.hibernate.mapping.Column(filledSlots)]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1321) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1160) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
... 162 common frames omitted

AppServiceService 使用关系数据库中的存储库,而 Rule 和 FilledSlots 对象位于 MongoDB 数据库中。我怀疑我们在两个数据库的配置中遗漏了一些东西。

关系数据库的配置如下:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = Constants.PERSISTENCE_PACKAGE)
public class DatabaseConfig {

@Value("${jdbc.jndi.url}")
private String jndiUrl;

@Value("${application.database}")
private String database;

@Bean(name = Constants.DATASOURCE)
@Primary
public DataSource dataSource() {
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
dsLookup.setResourceRef(true);
return dsLookup.getDataSource(jndiUrl);
}

@Bean(name = Constants.ENTITY_MANAGER_FACTORY)
@Primary
public EntityManagerFactory entityManagerFactory() {
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.valueOf(database));
vendorAdapter.setGenerateDdl(true);
if (database.equalsIgnoreCase(Constants.SQL_SERVER)) {
vendorAdapter.setDatabasePlatform(Constants.HIBERNATE_SQL_SERVER_DIALECT);
} else if (database.equalsIgnoreCase(Constants.ORACLE)) {
vendorAdapter.setDatabasePlatform(Constants.HIBERNATE_ORACLE_DIALECT);
}
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setJpaVendorAdapter(vendorAdapter);
factory.setPackagesToScan(Constants.PERSISTENCE_PACKAGE);
factory.setDataSource(dataSource());
factory.setJpaDialect(new HibernateJpaDialect());

Map<String, Object> properties = factory.getJpaPropertyMap();
properties.put(Constants.HIBERNATE_NAMING_STRATEGY, NamingConfig.class.getName());
properties.put(Constants.HIBERNATE_ENTITY_MANAGER_FACTORY_NAME, Constants.ENTITY_MANAGER_FACTORY);
factory.afterPropertiesSet();
return factory.getObject();
}

@Bean(name = Constants.TRANSACTION_MANAGER)
@Primary
public PlatformTransactionManager transactionManager() {
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setEntityManagerFactory(entityManagerFactory());
return txManager;
}

@Bean(name = Constants.ENTITY_MANAGER)
@Primary
public EntityManager entityManager() {
EntityManagerFactory entityManagerFactory = entityManagerFactory();
EntityManager entityManager = entityManagerFactory.createEntityManager();
return entityManager;
}
}

MongoDB 的配置:

@Configuration
@EnableMongoRepositories(basePackages = Constants.PERSISTENCE_PACKAGE)
@ComponentScan(basePackages = Constants.VOICEWEB_PACKAGE,
excludeFilters =
{@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Configuration.class),
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = Controller.class),
@ComponentScan.Filter(type = FilterType.ANNOTATION, value = ControllerAdvice.class)})
public class MongoConfig extends AbstractMongoConfiguration{

@Value("${application.mongo.host}")
private String mongoHost;

@Value("${application.mongo.port}")
private String mongoPort;

@Value("${application.mongo.database}")
private String mongoDatabase;

@Override
protected String getDatabaseName() {
return mongoDatabase;
}

@Bean
@Override
public MongoClient mongoClient() {
return new MongoClient(mongoHost, Integer.parseInt(mongoPort));
}

@Bean(name="mongoDbFactory")
public MongoDbFactory mongoDbFactory() {
return new SimpleMongoDbFactory(this.mongoClient(), this.getDatabaseName());
}

@Bean(name="mongoTemplate")
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoClient(), mongoDatabase);
}

@Bean
@Override
public MappingMongoConverter mappingMongoConverter() throws Exception {
MappingMongoConverter mmc = super.mappingMongoConverter();
mmc.setTypeMapper(customTypeMapper());
return mmc;
}

@Bean
public MongoTypeMapper customTypeMapper() {
return new CustomMongoTypeMapper();
}

}

我注意到在 MongoDB 中,没有数据源,而是使用主机和端口实例化 MongoClient。有没有办法在 Hibernate 中定义 MongoDB 是一个不同的数据源?

编辑

规则实体:

@Document(collection = Constants.RULES )
@Entity
public class Rule extends AbstractMongoEntity {

@DBRef
private Intention intention;

@DBRef
private List<FilledSlot> filledSlots = new ArrayList<>();

@DBRef
private Segment segment;

@DBRef
private Task task;


public Rule() {
}

public Rule(Intention intention, List<FilledSlot> filledSlots, Segment segment, Task task) {
this.intention = intention;
this.filledSlots = filledSlots;
this.segment = segment;
this.task = task;
}

public Rule(String id, Intention intention, List<FilledSlot> filledSlots, Segment segment, Task task) {
this._id = id;
this.intention = intention;
this.filledSlots = filledSlots;
this.segment = segment;
this.task = task;
}

public Intention getIntention() {
return intention;
}

public void setIntention(Intention intention) {
this.intention = intention;
}


public List<FilledSlot> getFilledSlots() {
return filledSlots;
}

public void setFilledSlots(List<FilledSlot> filledSlots) {
this.filledSlots = filledSlots;
}

public Segment getSegment() {
return segment;
}

public void setSegment(Segment segment) {
this.segment = segment;
}

public Task getTask() {
return task;
}

public void setTask(Task task) {
this.task = task;
}

@Override
public String toString() {
return "Rule{" +
"intention=" + intention +
", filledSlots=" + filledSlots +
", segment=" + segment +
", task=" + task +
", id='" + _id + '\'' +
'}';
}
}

和 FilledSlot 实体:

@Document(collection = Constants.SLOTS)
@Entity
public class FilledSlot extends AbstractMongoEntity {

private String slotKey;
private String slotValue;

public FilledSlot(){
}

@PersistenceConstructor
public FilledSlot(String slotKey, String slotValue){
setSlotKey(slotKey);
setSlotValue(slotValue);
}

public String getSlotKey() {
return slotKey;
}

public void setSlotKey(String slotKey) {
this.slotKey = slotKey;
}

public String getSlotValue() {
return slotValue;
}

public void setSlotValue(String slotValue) {
this.slotValue = slotValue;
}

@Override
public String toString() {
return "FilledSlot{" +
"slotKey='" + slotKey + '\'' +
", slotValue='" + slotValue + '\'' +
", _id='" + _id + '\'' +
'}';
}
}

最佳答案

关系数据源的实体与 MongoDB 的实体位于不同的 jar 文件中。问题是两个配置的持久化包是一样的,所以通过改变mongo db配置中的持久化包问题就解决了

关于java - 使用 Hibernate 定义两个数据源——一个关系型数据源和一个 NoSQL 型数据源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56564523/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com