Reputation: 831
In our project we have two databases: one relational (ms sql server) and one NoSQL (MongoDB). When I start the project I get this error:
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 uses a repository from the Relational database, while the Rule and FilledSlots objects are in the MongoDB database. I suspect that we are missing something in the configuration of the two databases.
The configuration for the relational database is the below:
@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;
}
}
The configuration for 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();
}
}
I noticed that in MongoDB, there is no datasource but instantiates the MongoClient using the host and the port. Is there a way to define in Hibernate that MongoDB is a different datasource?
EDIT
The Rule Entity:
@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 + '\'' +
'}';
}
}
and the FilledSlot entity:
@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 + '\'' +
'}';
}
}
Upvotes: 2
Views: 182
Reputation: 831
The entities of the relational datasource was in a different jar file from those of MongoDB. The problem was that the persistence package of both configurations was the same, so by changing the persistence package in mongo db configuration the problem was solved
Upvotes: 2