Organizacja modułów przy 2 datasource'ach.

1

Cześć. Mam wymaganie aby zapisać w pewnym procesie 2 encje. Encja: FirstEntity oraz SecondEntity reprezentują 2 tabelki z różnych baz danych.

screenshot-20241112192054.png

Klasa PostgresSqlDataSourceConfig szuka repozytorium oraz encji z module1 (ThirdEntity) oraz module2 (FirstEntity). PostgresSqlDataSourceConfig umieszczona jest w module shared, ponieważ reszta modułów używa tej konfiguracji do połączenia się z bazą.


@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackages = {"com.example.demo.module1", "com.example.demo.module2"})
class PostgresSqlDataSourceConfig 

Klasa MySqlDataSourceConfig szuka repozytoria oraz encji z module2 (SecondEntity). MySqlDataSourceConfig umieszczona jest w module2, ponieważ tylko module2 używa konfiguracji do połączenia z bazą.

@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackages = "com.example.demo.module2")
class MySqlDataSourceConfig {

Przy starcie aplikacji oczywiście Spring nie pozwala MySqlDataSourceConfig na skanowanie repozytoria, które już jest wykryte przez PostgresSqlDataSourceConfig. (Z racji tego, że skanuje scieżkę: com.example.demo.module2.
Chcę zachować taką strukturę modułów, gdzie jedynym punktem wejścia jest fasada.
Wiem, że mógłbym rozwiązać ten problem tworzyć podpakiet w pakiecie module2 i umieścić w nim encję FirstEntity oraz repozytorium FirstEntityRepository. Następnie w klasie konfiguracyjnej PostgresSqlDataSourceConfig podać podpakiet w adnotacji @EnableJpaRepositories.
W takim podejściu encja oraz repozytorium musiałoby być publiczne (czego chciałbym uniknąć), ponieważ w fasadzie byłby zapis do bazy.

Reasumując: Problemem jest fakt, że obie encje należą do jednej domeny natomiast znajdują się w innych bazach przez co obie klasy konfiguracyjne się gryzą, ponieważ skanują te same ścieżki. W jaki najrozsądniejszy sposób umieścić taką encję i repozytorium aby zachować modułowość i nie wystawiać jako public?

Z góry dzięki za odpowiedź.

1

Podpakiety Ci nic nie zmienią.
Musisz mieć dwa osobne datasource, każde ze swoim url/usrname/pass.
Mając ten datasource musiałbyś użyć jdbcTemplate.
Wtedy miałbyś dwa templaty w fasadzie i (chyba) mógłbyś użyć @transactional
Jeden template zapisuje do jednej tabeli w pierwszej bazie, drugi template w drugiej.
Coś w ten deseń:

public DataSource dataSource() {
    return DataSourceBuilder.create()
        .url(datasourceUrl)
        .driverClassName(datasourceDriverClassName)
        .username(datasourceUsername)
        .password(datasourcePassword)
        .build();
  }

 public NamedParameterJdbcTemplate jdbcTemplate(
      @Qualifier("dataSource") DataSource dataSource) {
    return new NamedParameterJdbcTemplate(dataSource);
  }

Ewentualnie pierwszy rekord z google: https://www.baeldung.com/spring-data-jpa-multiple-databases

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.