How can i connect to 2 different Schemas on one datasource in springboot

Viewed 728

I am trying to extract data from multiple databases in different servers. This has been successful after configuring different Data sources as shown in my code however i cannot see to configure 2 different Data sources on the same connection.

I have tried to create 2 beans within the config file but i would still need to set the Data source.

@Configuration
@EnableJpaRepositories(basePackages = {"balances.Repository.World"},
        entityManagerFactoryRef = "ASourceEntityManager",transactionManagerRef = "ASourceTransactionManager")
@EnableTransactionManagement
public class World{
    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean ASourceEntityManager() {

        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(ASourceDatasource());
        em.setPackagesToScan(new String("balances.Repository.World"));
        em.setPersistenceUnitName("ASourceEntityManager");
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.dialect",env.getProperty("app.datasource.ASource.hibernate.dialect"));
        properties.put("hibernate.show-sql",env.getProperty("app.datasource.ASource.show-sql"));
        em.setJpaPropertyMap(properties);
        return em;

    }
 
    @Bean
    @ConfigurationProperties(prefix = "app.datasource.ASource")
    public DataSource ASourceDatasource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        
  dataSource.setDriverClassName(env.getProperty("app.datasource.ASource.driverClassName"));
        dataSource.setUrl(env.getProperty("app.datasource.ASource.url"));
        dataSource.setUsername(env.getProperty("app.datasource.ASource.username"));
        dataSource.setPassword(env.getProperty("app.datasource.ASource.password"));

        return dataSource;
    }

    @ConfigurationProperties(prefix = "app.datasource.ASourceB")
    public DataSource ASourceDatasource() {

        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(env.getProperty("app.datasource.ASourceB.driverClassName"));
        dataSource.setUrl(env.getProperty("app.datasource.ASourceB.url"));
        dataSource.setUsername(env.getProperty("app.datasource.ASourceB.username"));
        dataSource.setPassword(env.getProperty("app.datasource.ASourceB.password"));

        return dataSource;
    }


    @Bean
    public PlatformTransactionManager ASourceTransactionManager() {

        JpaTransactionManager transactionManager
                = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(
                ASourceEntityManager().getObject());
        return transactionManager;
    }


1 Answers

After some thought i have come up with a workaround that might be a bit hacky but gets the job done. Instead of declaring a new database connection for the second schema in my app.properties i have used one connection. I placed all my entities in one model package and used a native query to access the other schema. In the native query i would then specify the schema eg:

 select * from DATABASE1.Id;  

This solution does not scale well as it would create a lot of work when dealing with a large number of entities so if there is a way of specifying the schema in the repository that would also help.

I tried using the entity attributes to define my schema but jpa seems to be ignoring it and prefixing the table with the wrong schema for example if i annotate my class with the following

@Table(name = "Payment", schema = "DATABASE1", catalog = "")

The resulting query would be "select * from DATABASE2.Payment" instead of select * from DATABASE1.Payment

Related