I have springBatch App where I was using multiple datasources which I configured as below which is pretty much straight forward. It was working fine.
How to use 2 or more databases with spring?
Now I had to integrate it to Jhipster project. I did similar kind of configuration in application.yml. I removed auto generated Datasource from application.yml and added configurations similar to above post and injected the primary Datasource in DataBaseConfiguration.java which is Jhipster generated class. With this configuration I am unable to do CRUD operation on Database entities form JHipster UI. I am not seeing any errors in logs.
I am not sure what's the right/simple way of configuring multiple datasources in Jhipster project. A sample example utilizing multiple databases would give a good start for me. I didn't find much resources on this.
Below are code sample's for changes I performed to have multiple datasources in JHipster
# ===================================================================
# Spring Boot configuration for the "dev" profile.
#
# This configuration overrides the application.yml file.
#
# More information on profiles: http://www.jhipster.tech/profiles/
# More information on configuration properties: http://www.jhipster.tech/common-application-properties/
# ===================================================================
# ===================================================================
# Standard Spring Boot properties.
# Full reference is available at:
# http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
# ===================================================================
spring:
profiles:
active: dev
include: swagger
devtools:
restart:
enabled: true
livereload:
enabled: false # we use gulp + BrowserSync for livereload
jackson:
serialization.indent_output: true
jpa:
database-platform: org.hibernate.dialect.Oracle12cDialect
database: ORACLE
show-sql: true
properties:
hibernate.id.new_generator_mappings: true
hibernate.cache.use_second_level_cache: false
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: true
hibernate.default_schema: ********x
mail:
host: localhost
port: 25
username:
password:
messages:
cache-seconds: 1
thymeleaf:
cache: false
batch:
job:
enabled: false
liquibase:
contexts: dev
# ===================================================================
# To enable SSL, generate a certificate using:
# keytool -genkey -alias ********x-storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
#
# You can also use Let's Encrypt:
# https://maximilian-boehm.com/hp2121/Create-a-Java-Keystore-JKS-from-Let-s-Encrypt-Certificates.htm
#
# Then, modify the server.ssl properties so your "server" configuration looks like:
#
# server:
# port: 8443
# ssl:
# key-store: keystore.p12
# key-store-password: <your-password>
# keyStoreType: PKCS12
# keyAlias: ********x
# ===================================================================
server:
port: 8080
# ===================================================================
# JHipster specific properties
#
# Full reference is available at: http://www.jhipster.tech/common-application-properties/
# ===================================================================
jhipster:
http:
version: V_1_1 # To use HTTP/2 you will need SSL support (see above the "server.ssl" configuration)
# CORS is only enabled by default with the "dev" profile, so BrowserSync can access the API
cors:
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
exposed-headers: "Authorization"
allow-credentials: true
max-age: 1800
security:
authentication:
jwt:
secret: my-secret-token-to-change-in-production
# Token is valid 24 hours
token-validity-in-seconds: 86400
token-validity-in-seconds-for-remember-me: 2592000
mail: # specific JHipster mail property, for standard properties see MailProperties
from: ********x@localhost
base-url: http://127.0.0.1:8080
metrics: # DropWizard Metrics configuration, used by MetricsConfiguration
jmx.enabled: true
graphite: # Use the "graphite" Maven profile to have the Graphite dependencies
enabled: false
host: localhost
port: 2003
prefix: ********x
prometheus: # Use the "prometheus" Maven profile to have the Prometheus dependencies
enabled: false
endpoint: /prometheusMetrics
logs: # Reports Dropwizard metrics in the logs
enabled: false
report-frequency: 60 # in seconds
logging:
logstash: # Forward logs to logstash over a socket, used by LoggingConfiguration
enabled: false
host: localhost
port: 5000
queue-size: 512
# ===================================================================
# Application specific properties
# Add your own application properties here, see the ApplicationProperties class
# to have type-safe configuration, like in the JHipsterProperties above
#
# More documentation is available at:
# http://www.jhipster.tech/common-application-properties/
# ===================================================================
datasource.********x.type: com.zaxxer.hikari.HikariDataSource
datasource.********x.url: "jdbc:oracle:thin:@********x"
datasource.********x.username: ********x
datasource.********x.password: ********x
datasource.********xy.type: com.zaxxer.hikari.HikariDataSource
datasource.********xy.url: "jdbc:oracle:thin:@yyyyyy"
datasource.********xy.username:********x
datasource.********xy.password: "********x"
package com.********x
import io.github.jhipster.config.JHipsterConstants;
import io.github.jhipster.config.liquibase.AsyncSpringLiquibase;
import liquibase.integration.spring.SpringLiquibase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration
@EnableJpaRepositories("com.********x")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement
public class DatabaseConfiguration {
private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);
private final Environment env;
public DatabaseConfiguration(Environment env) {
this.env = env;
}
@Autowired
@Qualifier("********x")
private DataSource dataSource;
@Bean
public SpringLiquibase liquibase(@Qualifier("taskExecutor") TaskExecutor taskExecutor
, LiquibaseProperties liquibaseProperties) {
// Use liquibase.integration.spring.SpringLiquibase if you don't want Liquibase to start asynchronously
SpringLiquibase liquibase = new AsyncSpringLiquibase(taskExecutor, env);
liquibase.setDataSource(dataSource);
liquibase.setChangeLog("classpath:config/liquibase/master.xml");
liquibase.setContexts(liquibaseProperties.getContexts());
liquibase.setDefaultSchema(liquibaseProperties.getDefaultSchema());
liquibase.setDropFirst(liquibaseProperties.isDropFirst());
if (env.acceptsProfiles(JHipsterConstants.SPRING_PROFILE_NO_LIQUIBASE)) {
liquibase.setShouldRun(false);
} else {
liquibase.setShouldRun(liquibaseProperties.isEnabled());
log.debug("Configuring Liquibase");
}
return liquibase;
}
}
So I injected primary Datasource in DatabaseConfiguration.java and using other datasource where required. Both these datasources are created similar to the above post like how spring suggests.
Here is how I make two datasource work in JHipster project :
The default datasource properties generate by JHipster:
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:h2:file:./target/h2db/db/mockpartenaire;DB_CLOSE_DELAY=-1
username: mockpartenaire
password:
Configs for the JHispter default 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 customerEntityManagerFactory(
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;
}
}
The second datasource properties:
partner:
datasource:
type: com.zaxxer.hikari.HikariDataSource
url: jdbc:postgresql://localhost:5432/partner
username: partner
password: partner
driver-class-name: org.postgresql.Driver
The second datasource configs :
@Configuration
@EnableTransactionManagement
@EntityScan(basePackages = "com.my.test.custom.domain")
@EnableJpaRepositories(transactionManagerRef = "partnerTransactionManager", entityManagerFactoryRef = "partnerEntityManagerFactory", basePackages = "com.my.test.custom.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 customerEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
LocalContainerEntityManagerFactoryBean emf = builder
.dataSource(partnerDataSource())
.packages(TestPost.class)
.persistenceUnit("partner")
.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;
}
}
The default datasource configured by JHipster will continue to work it's entities. For your custom entities using the second datasource, here is the repository configuration :
@SuppressWarnings("unused")
@Repository
@Transactional("partnerTransactionManager")
@PersistenceContext(name = "partnerEntityManagerFactory")
public interface TestPostRepository extends JpaRepository<TestPost,Long>{
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With