Closed meantiger closed 5 years ago
@meantiger Do you mean multi-store?
As I understand you could create separate configs for them if you want to use JPA with CosmosDB.
@Configuration
@EnableJpaRepositories(entityManagerFactoryRef = "customerEntityManagerFactory",
transactionManagerRef = "customerTransactionManager",
basePackages = "xxx.xxx.your-jpa-package")
@EnableTransactionManagement
public class ConifgA {
@Bean
PlatformTransactionManager customerTransactionManager() { }
@Bean
LocalContainerEntityManagerFactoryBean customerEntityManagerFactory() { }
@Bean
DataSource customerDataSource() { }
}
@Configuration
@EnableDocumentDbRepositories(basePackages = "xxx.xxx.your-cosmosdb-package")
@EnableConfigurationProperties(DocumentDbProperties.class)
public class ConfigB extends AbstractDocumentDbConfiguration {
@Autowired
private DocumentDbProperties properties;
@Override
public DocumentDBConfig getConfig() {
return DocumentDBConfig.builder(properties.getUri(),
properties.getKey(),
properties.getDatabase()).build();
}
}
@saragluna First of all Thx U for comment. Yes. As U mentioned I try multi-store. And I did what U said. However unfortunately It's not working well.........
So, I upload my details src.
First I import this spring-data-jpa
and my application.properties are like this
azure.cosmosdb.uri=(DBURI)
# Specify the access key for your database.
azure.cosmosdb.key=(DBKEY)
# Specify the name of your database.
azure.cosmosdb.database=(DBNAME)
# Specify the information of your user DB.
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.jdbc-url=jdbc:mysql:(DBURI)
spring.datasource.username=(DBusername)
spring.datasource.password=(DBuserpassword)
and my code is like this I think the DocumentDBConfig works well that I just write exactly same as U. However the mysqlConfig.... I constuct your code like this.
@primary
@bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder, @qualifier("dataSource") DataSource dataSource) {
return builder
.dataSource(dataSource)
.packages("=====.domain")
.persistenceUnit("customer")
.build();
}
However Could not autowire. no beans of EntityManagerFactoryBuilder error popup. this kind of error will be fine when I use spring-boot-starter-data-jpa this. but I use that it cannot connect with cosmos and mysql. I guess I'm doing something wrong...... do I made wrong config code?
*PS thx u for your help.
@meantiger If you don't want to customize EntityManager or TransactionManager, you can simply remove these beans:
@Bean
PlatformTransactionManager customerTransactionManager() { }
@Bean
LocalContainerEntityManagerFactoryBean customerEntityManagerFactory() { }
@Bean
DataSource customerDataSource() { }
If you have to customize EntityManager and since you're using spring-data-jpa, you can customize the bean like this:
@Bean
LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(DataSource dataSource) {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(ConfigB.class.getPackage().getName());
return factoryBean;
}
@saragluna Really thank U again. and I hope This is my Last Question. Below is My Code. ` @Configuration @EnableJpaRepositories(entityManagerFactoryRef = "customerEntityManagerFactory", transactionManagerRef = "customerTransactionManager", basePackages = "com.sktelecom.iottelemetry.User") @EnableTransactionManagement public class MySQLConfig {
@Autowired
private Environment env;
@Primary
@Bean(name = "customerTransactionManager")
PlatformTransactionManager customerTransactionManager(@Qualifier("customerEntityManagerFactory") EntityManagerFactory entityManagerFactory ){
return new JpaTransactionManager(entityManagerFactory);
}
@Primary
@Bean(name = "customerEntityManagerFactory")
LocalContainerEntityManagerFactoryBean customerEntityManagerFactory(DataSource dataSource) {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setGenerateDdl(true);
LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
factoryBean.setDataSource(dataSource);
factoryBean.setJpaVendorAdapter(jpaVendorAdapter);
factoryBean.setPackagesToScan(MySQLConfig.class.getPackage().getName());
return factoryBean;
}
@Primary
@Bean(name = "datasource")
DataSource customerDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getProperty("spring.datasource.driver-class-name"));
dataSource.setUrl(env.getProperty("spring.datasource.url"));
dataSource.setUsername(env.getProperty("spring.datasource.username"));
dataSource.setPassword(env.getProperty("spring.datasource.password"));
return dataSource;
}
} `
This is my MySQL Config code. and My properties are Like this
azure.cosmosdb.uri=(MY DB URI) azure.cosmosdb.key=(MYDB KEY) azure.cosmosdb.database=(MYDBNAME)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.jdbc-url=(MY DB URL) spring.datasource.username=(MY DB USERNAME) spring.datasource.password=(MY DB PASSWORD)
Howerver This kind of error still occur.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerEntityManagerFactory' defined in class path resource [com/------/--------/Config/MySQLConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'customerEntityManagerFactory' threw exception; nested exception is java.lang.NoClassDefFoundError: org/hibernate/Session
Can U teach me how can I make whole MySQL config code?
Thx U For your kindness.
@meantiger I'm thinking is it possible for you to create a minimal project so I can help to find the problem?
@saragluna THX. https://github.com/meantiger/iot-device-telemetry This is my minimal project.
Thx U.
@meantiger after test CosmosDB can work with multi-store, you could check it with your repo PR. Close this issue.
@saragluna It's Work! and I merge it my real project. and It work well too. Sincerely Thx U.
*PS If you do not mind, can I suggest one thing?
There are a lot of people who want to use cosmos DB & sql DB in the same time like me. Cuz. CosmosDB is expensive and in process sometimes we need sql DB. And this kind of config is different from common multi-source database use.
In common case should make two kind of config like my code.
So, I think It would be really great make cosmos config guide and this kind of case guide upload in azure-cosmos document or starting guide.
I have tried to connect with 2 datasource of cosmos but not able to connect. I have tried all the solution given but not a single thing is working.
@Configuration @EnableCosmosRepositories(basePackages = "com.bajrang.repositories.kooprepositories") public class KoopCosmosConfig extends AbstractCosmosConfiguration { @Value("${spring.koop.azure.cosmosdb.uri}") private String uri; @Value("${spring.koop.azure.cosmosdb.key}") private String key; @Value("${spring.koop.azure.cosmosdb.database}") private String database;
@Bean
@Primary
public CosmosDBConfig koopCosmosDBConfig() {
CosmosDBConfig cosmosDBConfig = CosmosDBConfig.builder(uri, key, database).build();
return cosmosDBConfig;
}
===================================
@Configuration @EnableTransactionManagement @EnableCosmosRepositories(basePackages = "com.bajrang.repositories.galactusrepositories") public class GalactusCosmosConfig extends AbstractCosmosConfiguration { @Value("${spring.galactus.azure.cosmosdb.uri}") private String uri; @Value("${spring.galactus.azure.cosmosdb.key}") private String key; @Value("${spring.galactus.azure.cosmosdb.database}") private String database;
@Bean
public CosmosDBConfig galactusCosmosDBConfig() {
CosmosDBConfig cosmosDBConfig = CosmosDBConfig.builder(uri, key, database).build();
return cosmosDBConfig;
}
This error is comes
Parameter 0 of method cosmosTemplate in com.microsoft.azure.spring.data.cosmosdb.config.AbstractCosmosConfiguration required a single bean, but 2 were found:
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
Process finished with exit code 1
I have tried with this configuration but not able to connect with two data source.
Please help me I urgently need to do this but I am not able to do. I need to connect with 2 databases but it is not happening.
@bajrangprasad01
AFAIK the current implementation doesn't support multiple databases. @kushagraThapar could help provide more info on this.
@bajrangprasad01
AFAIK the current implementation doesn't support multiple databases. @kushagraThapar could help provide more info on this.
Thank You for the information.
@bajrangprasad01 - This will be supported in upcoming spring-data-cosmosdb release train v3.x.x
Please could share with me the final solution for this issue @meantiger
I need to use cosmos and spring jpa for mssql in the same project @kushagraThapar Could please give me with headlines how to do that and if you have a POC that should be awesome and thank you a lot for your reply.
In that case, I think you just need to use one single cosmos db account and map it through your application.properties files. Unfortunately we don't have a POC for the same, however, implementing it should be straightforward. If you can give it a try, I can help out with any issues that you may face.
@moabduikea sorry for late. I'm not sure. cuz this project is so old to me. Use spring boot.
pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
<version>2.0.13</version>
</dependency>
CosmosConfig.java
package com.test.iottelemetry.Config;
import com.microsoft.azure.spring.autoconfigure.cosmosdb.DocumentDBProperties;
import com.microsoft.azure.spring.data.cosmosdb.config.AbstractDocumentDbConfiguration;
import com.microsoft.azure.spring.data.cosmosdb.config.DocumentDBConfig;
import com.microsoft.azure.spring.data.cosmosdb.repository.config.EnableDocumentDbRepositories;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableDocumentDbRepositories(basePackages = "com.test.iottelemetry.devicetelemetry")
@EnableConfigurationProperties(DocumentDBProperties.class)
public class CosmosConfig extends AbstractDocumentDbConfiguration {
@Autowired
private DocumentDBProperties properties;
@Override
public DocumentDBConfig getConfig() {
return DocumentDBConfig.builder(properties.getUri(),
properties.getKey(),
properties.getDatabase()).build();
}
}
MySQLConfig.java
package com.test.iottelemetry.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@EnableJpaRepositories(
basePackages = "com.test.iottelemetry.User")
@EnableTransactionManagement
public class MySQLConfig {
}
in this case. I use UserInfo in MySQL and iottelemetry in CosmosDB So in UserInfo class use Entity annotation and in Iottelemetry class use Document annotation I hope It will help U.
In formal case If I want to use multiple datasource in Spring boot with JPA (For Example, Use Mysql For UserInfo & Use h2 for merchandise data)
I set the properties & just make two Kinds of Config like this
@Configuration @EnableTransactionManagement @EnableJpaRepositories( basePackages = {"====.repository"}) public class CustomerDataSourceConfig {
@Primary @Bean(name = "dataSource") @ConfigurationProperties(prefix = "====.datasource") public DataSource dataSource() { return DataSourceBuilder.create().build(); }
@Primary @Bean(name = "entityManagerFactory") public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, @Qualifier("dataSource") DataSource dataSource) { return builder .dataSource(dataSource) .packages("=====.domain") .persistenceUnit("customer") .build(); }
@Primary @Bean(name = "transactionManager") public PlatformTransactionManager transactionManager( @Qualifier("entityManagerFactory") EntityManagerFactory entityManagerFactory) { return new JpaTransactionManager(entityManagerFactory); } }
But If I want to use Multiple DataSource(With CosmosDB) this kind of work dosen't work anymore. I should make different kind of config? or Is there any way I can use multiple datasource with cosmosDB? (ex. Use Mysql For UserInfo & Use CosmosDB for merchandise data)
thx.