1

How can I create 2 database connections using spring?

The connections need to have separate datasource and jpa(for show-sql and properties.hibernate.dialect) properties for e.g.

# Foo
foo.datasource.url=...
foo.jpa.properties.hibernate.dialect=... # H2
# Bar
bar.datasource.url=...
bar.jpa.properties.hibernate.dialect=... # ORACLE

What I want to achieve is not the configuration itself but rather the way to configure the properties using application.properties

All I could find Is creating 2 datasources. So I came up with a code that does this, but it looks dirty and it does not support jpa.show-sql only jpa.properties.hibernate.show_sql.

In the code I read the properties from spring using @ConfigurationProperties flatten the Map(foo: { jpa: { properties: { database: "H2" } } } } -> { "foo.jpa.properties.database": "H2" }) and call EntityManagerFactoryBuilder.Builder#properties(Map)

Do anyone have a better solution?


My code:

// I Copied the code by hand because we code on isolated network
private static final String NAME = "foo"

@Bean
@ConfigurationProperties(NAME + "datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

@Bean
public EntityManagerFactory entityManagerFactory(DataSource dataSource, Map<String,String> properties, EntityManagerFactoryBuilder builder) {
    return builder.dataSource(dataSource)
        .packages(NAME + ".entitites")
        .properties(properties)
        .persistenceUnit(NAME)
        .build()
}


@Bean
@ConfigurationProperties(NAME + "jpa.properties")
public Map<String, ?> propertiesNotFlatten() {
    retur new HashMap<String, ?>();
}

@Bean
public Map<String, String> properties(Map<String, ?> propertiesNotFlatten) {
    return flatten(propertiesNotFlatten)
        .collect(toMap(Entry::getKey, Entry::getValue));
}

private static Stream<Entry<String, String> flatten(Map<String, ?> map) {
    return map.entrySet()
        .stream()
        .flatMap(x -> x.getValue() instanceof String
            ? Stream.of((Entry<String, String>)x)
            : flatten(((Map<String, ?>)x.getValue())).map(y -> new SimpleEntry<>(
                x.getKey() + "." + y.getKey(),
                y.getValue()
            ))
        );
}

Notice that my code works and I just want to know how to do this better(spring must have a better way to do this)

Ido Sorozon
  • 272
  • 1
  • 12

0 Answers0