cheradikov
cheradikov

Reputation: 21

How can I connect two different database(mongo and postgres) in springboot with JPA?

I'm making mongo to postgres migraiton tool with springboot. But when I try to connect with mongo and postgres base on this documents, spring just raise dataSource or dataSourceClassName or jdbcUrl is required. error.

this is my application.yml

spring:
  datasource:
    legacy:
      url: "jdbc:postgresql://localhost:5432/postgres"
      username: "root"
      password: "root"

    migration:
      url: "jdbc:mongodb://localhost:27017"
      username: "root"
      password: "root"
      database: "fromdb"

and to use two different types of DBMS, I config my configurations. (If it doesn't required, please let me know better way) and because of hibernate.dialect doesn't support MongoDBDialect, it also raise Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set error.

this is my legacy db configuration code

import part

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "migrationEntityManager",
        transactionManagerRef = "migrationTransactionManager",
        basePackages = "com.dbmigrater.DBMigrater.repository.migration"
)
public class MigrationDBConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.hikari.bootdb1")
    public DataSource migrationDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager migrationTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(migrationEntityManager().getObject());

        return transactionManager;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean migrationEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(migrationDataSource());
        em.setPackagesToScan("com.dbmigrater.model.migration");

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter);

        Map<String, Object> properties = new HashMap<>();
        properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
        properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
        //=================This part is setting dialect, and error=====================//
        properties.put("hibernate.dialect", org.hibernate.dialect.MongoDBDialect);
        //=============================================================================//
        em.setJpaPropertyMap(properties);

        return em;
    }
}

Because mentioned error, I should set dedicated part in my upper code. but it also causes errorproperties.put("hibernate.dialect", org.hibernate.dialect.MongoDBDialect); because hibernate.dialect does not support MongoDBDialect!!

How can I connect these two databases(mongo, postgres)??

Upvotes: 1

Views: 1186

Answers (1)

cheradikov
cheradikov

Reputation: 21

I solved it myself. configuration code should be modified like below:

package com.dbmigrater.DBMigrater.config;

import org.hibernate.dialect.PostgreSQL82Dialect;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy;
import org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy;
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.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "migrationEntityManager",
        transactionManagerRef = "migrationTransactionManager",
        basePackages = "com.dbmigrater.DBMigrater.repository.migration"
)
public class MigrationDBConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.migration")
    public DataSource migrationDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public PlatformTransactionManager migrationTransactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(migrationEntityManager().getObject());

        return transactionManager;
    }

    @Bean
    @Primary
    public LocalContainerEntityManagerFactoryBean migrationEntityManager() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(migrationDataSource());
        em.setPackagesToScan("com.dbmigrater.DBMigrater.entity.migration");

        HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(adapter);

        Map<String, Object> properties = new HashMap<>();
        properties.put("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
        properties.put("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
        properties.put("hibernate.dialect", PostgreSQL82Dialect.class.getName());

        em.setJpaPropertyMap(properties);

        return em;
    }
}

point is inner parameter of @CongifurationProperties() should be matched with application.yml. In this case, I change my parameter by spring.datasource.migraiton.

and because of I face the next error for mongo driver, I change my application.yml like below

spring:
  datasource:
    legacy:
      driver-class-name: "mongodb.jdbc.MongoDriver"
      jdbcUrl: "jdbc:mongodb://localhost:27017"
      username: "root"
      password: "root"
      database: "fromdb"
    migration:
      jdbcUrl: "jdbc:postgresql://localhost:5432/postgres"
      username: "root"
      password: "root"

Also, mongodb.jdbc.MongoDriver is not a exist class, I face another error: java.lang.RuntimeException: Failed to load driver class mongodb.jdbc.MongoDriver in either of HikariConfig class loader or Thread context classloader

If I solve this secondary problem, I will leave the solutions

Upvotes: 1

Related Questions