4

I have a problem, I'm trying to use two Oracle databases in spring boot using DataSource, The DataSource wiht the @Primay annotation works fine but the oher one only gives me:

SQL Error: 942, SQLState: 42000
ORA-00942: table or view does not exist

I don't have idea what I should do now. Any help will be welcomed. Thanks!

application.properties

spring.datasource.url=jdbc\:oracle\:thin\:[connection] #Not showing for security
spring.datasource.password=[password]
spring.datasource.configuration.maximum-pool-size=30

spring.sgc-datasource.url=jdbc\:oracle\:[connection] #Not showing for security
spring.sgc-datasource.username=[user]
spring.sgc-datasource.password=[password]
spring.sgc-datasource.max-total=30

spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.database=default
spring.jpa.hibernate.ddl-auto=none

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.4</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.indra.vmo.edenorte</groupId>
    <artifactId>InMpData</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>InMpData</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>
        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

DatabaseConfiguration.java

package com.indra.vmo.edenorte.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.zaxxer.hikari.HikariDataSource;

@Configuration(proxyBeanMethods = false)
public class DatabaseConfiguration {
    
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties inMpDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.configuration")
    public HikariDataSource inMpDataSource(DataSourceProperties inMpDataSourceProperties) {
        return inMpDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
    
    @Bean
    @ConfigurationProperties("spring.sgc-datasource")
    public DataSourceProperties sgcDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    @Bean
    @ConfigurationProperties("spring.sgc-datasource.configuration")
    public HikariDataSource sgcDataSource(DataSourceProperties sgcDataSourceProperties) {
        return sgcDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
    
}

Repository from 1st DB

package com.indra.vmo.edenorte.repository.inmp;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.indra.vmo.edenorte.entity.inmp.MpLocalidadesCoordenadas;

@Repository
public interface IMpLocalidadesCoordenadasRepository extends JpaRepository<MpLocalidadesCoordenadas, String> {

}

Repository from 2nd DB

package com.indra.vmo.edenorte.repository.sgc;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import com.indra.vmo.edenorte.entity.sgc.Clientes;

@Repository
public interface IClientesRepository extends JpaRepository<Clientes, Integer> {

    @Query("select c from Clientes c where c.docId=?1")
    public Clientes findBydocId(String docId);
    
    @Query("select c from Clientes c where c.docId=?1 and c.tipDoc=?2")
    public Clientes findBydocIdU(String docId, String tipDoc);
}
1

2 Answers 2

2

SpringBoot auto-config works perfectly for a single datasource. For multiple datasources, you will need to manually configure the EntityManagerFactory beans for each of the datasources. See this article

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your link, it was helpful to solve this problem, I will post the full solution just in case someone has the similar issue
This is not completely true, see the Official Docs
2

I could resolve the problem with the following changes in my code:

application.properties

I changed the spring.jpa.hibernate.ddl-auto from none to validate and made some other chages

#Credenciales Datasource (InMpData)
spring.datasource.url=jdbc\:oracle\:thin\:[connection] #Not showing for security
spring.datasource.username=[user]
spring.datasource.password=[password]
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver

#Credenciales Datasource (SGC)
spring.sgcdatasource.url=jdbc\:oracle\:thin\:[connection] #Not showing for security
spring.sgcdatasource.username=[user]
spring.sgcdatasource.password=[password]
spring.sgcdatasource.driver-class-name=oracle.jdbc.driver.OracleDriver

#Hibernate config
spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
spring.jpa.hibernate.ddl-auto=validate

# HikariCP settings
# spring.datasource.hikari.*
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=5

pom.xml

Added a new dependency

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
</dependency>

Divided the DatabaseConfiguration.java in two separeated files InMpConfig.java and SgcConfig.java

InMpConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.indra.vmo.edenorte.repository.inmp", entityManagerFactoryRef = "inMpEntityManagerFactory", transactionManagerRef = "inMpTransactionManager")
public class InMpConfig {

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties inMpDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource.configuration")
    public DataSource inMpDataSource() {
        return inMpDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
    
    /*Primary Entity manager*/
    @Primary
    @Bean(name = "inMpEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean inMpEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(inMpDataSource()).packages("com.indra.vmo.edenorte.entity.inmp").build();
    }
    
    @Primary
    @Bean
    public PlatformTransactionManager inMpTransactionManager(
            final @Qualifier("inMpEntityManagerFactory") LocalContainerEntityManagerFactoryBean inMpEntityManagerFactory) {
        return new JpaTransactionManager(inMpEntityManagerFactory.getObject());
    }
    
}

SgcConfig.java

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.indra.vmo.edenorte.repository.sgc", entityManagerFactoryRef = "sgcEntityManagerFactory", transactionManagerRef = "sgcTransactionManager")
public class SgcConfig {

    @Bean
    @ConfigurationProperties("spring.sgcdatasource")
    public DataSourceProperties sgcDataSourceProperties() {
        return new DataSourceProperties();
    }
    
    @Bean
    @ConfigurationProperties("spring.sgcdatasource.configuration")
    public DataSource sgcDataSource() {
        return sgcDataSourceProperties().initializeDataSourceBuilder().type(HikariDataSource.class).build();
    }
    
    @Bean(name = "sgcEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean sgcEntityManagerFactory(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(sgcDataSource()).packages("com.indra.vmo.edenorte.entity.sgc").build();
    }
    
    @Bean(name = "sgcTransactionManager")
    public PlatformTransactionManager sgcTransactionManager(
            final @Qualifier("sgcEntityManagerFactory") LocalContainerEntityManagerFactoryBean sgcEntityManagerFactory) {
        return new JpaTransactionManager(sgcEntityManagerFactory.getObject());
    }
    
}

And made some changes to the models, such as add the @Table and @Column annotation

@Entity
@Data
@Table(name = "CLIENTES")
public class Clientes implements Serializable {

    @Id
    @NotNull
    @Column(name = "COD_CLI")
    private Integer codCli;
    
    @Column(name = "USUARIO")
    private String usuario;
    
    @Column(name = "F_ACTUAL")
    private Date fActual;

I hope this is helpful for someone else.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.