1

I generated already a simple jhipster project with this specs:

specs

But I would like to know how I add a new connection to a second DB (MySQL). So I want to use both DB (H2 (default DB) and the "new" mySQL)!

First I went to application-dev.yml and I change to this:

 #PrimaryDB
spring:
    datasource:
        type: com.zaxxer.hikari.HikariDataSource
        url: jdbc:h2:file:./target/h2db/db/********;DB_CLOSE_DELAY=-1
        username: **********
        password:

#PartnerDB
partner:
    datasource:
        type: com.zaxxer.hikari.HikariDataSource
        url: jdbc:mysql://localhost:******/partner
        username: root
        password: 
        driver-class-name: org.mysql.jdbc.Driver

Then I created a class to each one of my DB (one default and the another partner):

PrimaryDbConfig (H2 Default DB):

package com.*******.config;
import com.sun.corba.se.spi.orbutil.fsm.Input;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
public class PrimaryDbConfig {
    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSourceProperties defaultDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @Primary
    @ConfigurationProperties("spring.datasource")
    public DataSource defaultDataSource() {
        return defaultDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean(name = "entityManagerFactory")
    @Primary
    public LocalContainerEntityManagerFactoryBean defaultEntityManagerFactory(
        EntityManagerFactoryBuilder builder) {
        return builder
            .dataSource(defaultDataSource())
            .packages(Input.class)
            .persistenceUnit("default")
            .build();
    }

    @Bean(name = "transactionManager")
    @Primary
    public JpaTransactionManager db2TransactionManager(@Qualifier("entityManagerFactory") final EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}

PartnerDbConfig (new DB mySQL):

import com.*****.domain.******;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@EntityScan(basePackages = "com.*********.domain")
@EnableJpaRepositories(transactionManagerRef = "partnerTransactionManager", entityManagerFactoryRef = "partnerEntityManagerFactory", basePackages = "com.carrental.repository")
public class PartnerDbConfig {

    @Bean
    @ConfigurationProperties("partner.datasource")
    public DataSourceProperties partnerDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Bean
    @ConfigurationProperties("partner.datasource")
    public DataSource partnerDataSource() {
        return partnerDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean(name = "partnerEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean partnerEntityManagerFactory(
        EntityManagerFactoryBuilder builder) {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");

        LocalContainerEntityManagerFactoryBean emf = builder
            .dataSource(partnerDataSource())
            .packages(*****.class)
            .persistenceUnit("******")
            .build();
        emf.setJpaProperties(properties);
        return emf;
    }

    @Bean(name = "partnerTransactionManager")
    public JpaTransactionManager db2TransactionManager(@Qualifier("partnerEntityManagerFactory") final EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }
}

Finally I create a another class to exclude the autoconfiguration:

package com.******.config;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication(
    scanBasePackages = {"com.********"},
    exclude = { DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class})
@EnableTransactionManagement

public class SpringbootMultipleDatasourcesApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootMultipleDatasourcesApplication.class, args);
    }
}

I already have the connection to mySQL through IntelliJ IDEA. But I am getting errors and I don´t know how to have two connections two different DB's. I want to use the same entities and repository to both DB's. Any thoughts?

The 3 errors:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name '*****EntityManagerFactory' defined in class path resource [com/******/config/PartnerDbConfig.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: *******] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given; please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.

Caused by: javax.persistence.PersistenceException: [PersistenceUnit: *******] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given; please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.

Caused by: org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given; please either disable second level cache or set correct region factory using the hibernate.cache.region.factory_class setting and make sure the second level cache provider (hibernate-infinispan, e.g.) is available on the classpath.

New errors:

   org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfiguration' defined in file [C:\Users\Rui Portela Pereira\CarRental\target\classes\com\carrental\config\SecurityConfiguration.class]: Unsatisfied dependency expressed through constructor parameter 1; 

nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.core.userdetails.UserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

Questions to recap:

  • 1.To config my two data sources (url, username, password) I must change the application-dev.yml, application.yml or h2.server.properties?

  • 2.Then I have to create two classes to my two data sources (to h2 with primary annotations) and another to mysql, right? What should I do with the class "DataBaseConfiguration"?

  • 3.And finally, my repository and domain are the same to both datasources. Is that a trouble?

    • my path:
      • com.myapp
        • config
          • h2config
          • mysqlconfig
        • domain
        • repository
R. Pereira
  • 205
  • 1
  • 3
  • 10
  • As message says, the problem is in cache configuration, probably with your second datasource. Check configuration in app*.yml and in CacheConfiguration.java – Gaël Marziou Jan 16 '19 at 13:13
  • Thank you for your reply! @GaëlMarziou I went to my app.yml and I passed "hibernate 2nd level chache to false". It works but now I am getting more erros :/ I will edit my error exception above. – R. Pereira Jan 16 '19 at 15:25
  • Without the arguments of `.packages(***.class)` it's difficult to say. In my project, I pass package names like `.packages("com.example.app.domain")`, maybe User is not in this list of packages – Gaël Marziou Jan 16 '19 at 15:51
  • Thank you again, yes I changed it following your instructions but I still having problems. (I "refresh" the log error above) – R. Pereira Jan 16 '19 at 22:25
  • I did not have these problems, I suppose you disabled too much autoconfiguration – Gaël Marziou Jan 16 '19 at 23:31
  • Thank you one more time for your patience! Yes, I think the problem it's relate with that. Maybe you can help recap, answering to this questions above: Thank once again for your time :) – R. Pereira Jan 17 '19 at 00:28

0 Answers0