Spring Boot test configuration for multiple datasources

Viewed 2196

So I am trying to introduce some unit tests for my Spring Boot application and I am having a hard time trying to setup the config for the test environment. My application is configured to connect to two different Postgres databases as follows:

application.properties

spring.db1-datasource.jdbc-url= jdbc:postgresql://localhost:5432/db1
spring.db1-datasource.username= admin
spring.db1-datasource.password= admin
spring.db1-datasource.driverClassName= org.postgresql.Driver

spring.db2-datasource.jdbc-url= jdbc:postgresql://localhost:5432/db2
spring.db2-datasource.username= admin
spring.db2-datasource.password= admin
spring.db2-datasource.driverClassName= org.postgresql.Driver

FirstDbConfig.java

@Configuration
@PropertySource({"classpath:application.properties"})
@EnableJpaRepositories(
        basePackages = "org.myapp.database.db1.repository",
        entityManagerFactoryRef = "firstEntityManager",
        transactionManagerRef = "firstTransactionManager")
public class FirstDbConfig {
    @Autowired
    private Environment env;

    public FirstDbConfig() {
        super();
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean firstEntityManager() {
        final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(firstDataSource());
        em.setPackagesToScan("org.myapp.database.db1");

        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        em.setJpaVendorAdapter(vendorAdapter);
        final HashMap<String, Object> properties = new HashMap<String, Object>();
        properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
        em.setJpaPropertyMap(properties);

        return em;
    }

    @Bean
    @ConfigurationProperties(prefix="spring.db1-datasource")
    public DataSource firstDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    public PlatformTransactionManager firstTransactionManager() {
        final JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(firstEntityManager().getObject());
        return transactionManager;
    }
}

SecondDbConfig.java

Not including it because it's quite similar. Targets org.myapp.database.db2.repository

For my basic test, I am trying to test a simple service that injects one of these configured repositories. This looks like that:

MyServiceTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MyService.class)
@ContextConfiguration(
        classes = {FirstDbConfig.class, SecondDbConfig.class },
        loader= AnnotationConfigContextLoader.class
)
public class MyServiceTest {

    @InjectMocks
    private MyService myService;

    @Mock
    private FirstDbRepository dbRepository;

    @Test
    public void test() {
        ...
        // call to myService.method()
    }
}

Test fails with:

java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set at ...

It obviously has to do with hibernate.dialect not being set but no idea why that is the case. Any ideas?

2 Answers

Yes, we need to include this hibernate dialect, try including these 2 lines in your application.properties file

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto = update

Need to include this in application.properties file spring.jpa.database=default

Related