I have an application that needs to connect to two databases but the entities are repeated for both databases.
I managed to get the application to connect and persist the entity in both databases but I had to create two repositories, one for each database and I didn't find this approach correct.
There is a better way to do this management where I create a repository and define for it which connection it should use based on a flag for example.
First database configuration
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["xxx.xxx.domains.portadapter.repository.firstRepository"],
entityManagerFactoryRef = "firstEntityManegerFactory",
transactionManagerRef = "firstTransactionManager"
)
class FirstDatabaseConfiguration {
@Bean(name = ["firstDatasource"])
@ConfigurationProperties(prefix = "first.datasource")
fun dataSource(): DataSource? {
return DataSourceBuilder.create().build()
}
@Bean(name = ["firstEntityManegerFactory"])
fun firstEntityManegerFactory(
builder: EntityManagerFactoryBuilder, @Qualifier("firstDatasource") dataSource: DataSource?
): LocalContainerEntityManagerFactoryBean? {
return builder.dataSource(dataSource).packages("xxx").persistenceUnit("xxx")
.build()
}
@Bean(name = ["firstTransactionManager"])
fun firstTransactionManager(
@Qualifier("firstEntityManegerFactory") barEntityManagerFactory: EntityManagerFactory?
): PlatformTransactionManager? {
return JpaTransactionManager(barEntityManagerFactory!!)
}
}
Second Database Configuration
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = ["xxx.xxx.domains.portadapter.repository.secondRepository"],
entityManagerFactoryRef = "secondEntityManegerFactory",
transactionManagerRef = "secondTransactionManeger"
)
class secondDatabaseConfiguration {
@Primary
@Bean(name = ["secondDatasource"])
@ConfigurationProperties(prefix = "spring.datasource")
fun dataSource(): DataSource? {
return DataSourceBuilder.create().build()
}
@Primary
@Bean(name = ["secondEntityManegerFactory"])
fun secondEntityManegerFactory(
builder: EntityManagerFactoryBuilder, @Qualifier("secondDatasource") dataSource: DataSource?
): LocalContainerEntityManagerFactoryBean? {
return builder.dataSource(dataSource).packages("xxx").persistenceUnit("xxx")
.build()
}
@Primary
@Bean(name = ["secondTransactionManager"])
fun secondTransactionManager(
@Qualifier("secondEntityManegerFactory") barEntityManagerFactory: EntityManagerFactory?
): PlatformTransactionManager? {
return JpaTransactionManager(barEntityManagerFactory!!)
}
}
Repository for agegroup that persist the entity on the first database
interface FirstAgeGroupsRepository : JpaRepository<AgeGroups, Int> {
fun findBySispacId(sispacId : String): Optional<AgeGroups>
}
Repository for agegroup that persist the entity on the second database
interface SecondAgeGroupsRepository : JpaRepository<AgeGroups, Int> {
fun findBySispacId(sispacId : String): Optional<AgeGroups>
}
In this controller for example I would have to instantiate each of the repositories and define through a conditional which one I should use
@Service
class AgeGroupsController(
@Autowired val scoobyAgeGroupRepository: ScoobyAgeGroupsRepository,
@Autowired val fisiaAgeGroupRepository: FisiaAgeGroupsRepository
) {
fun saveAgeGroup(body: AgeGroupDto): ResponseDto {
return try {
val ageGroupFound: Optional<AgeGroups> = fisiaAgeGroupRepository.findBySispacId(body.sispacId)
if (!ageGroupFound.isEmpty) {
return ResponseDto(HttpStatus.FOUND, "Faixa etária ja existe, persistencia não realizada.")
}
val formatter = SimpleDateFormat("yyyy-MM-dd")
val ageGroup = AgeGroups(
body.ageGroupName, formatter.parse(body.createdAt), body.sispacId,
formatter.parse(body.updatedAt)
)
body.ageGroupIndexDescription?.let { ageGroup.setAgeGroupIndexDescription(it) }
fisiaAgeGroupRepository.save(ageGroup)
ResponseDto(HttpStatus.OK, "Faixa etária criada com sucesso!")
} catch (erro: Exception) {
print(erro.message)
ResponseDto(HttpStatus.BAD_REQUEST, erro.message)
}
}
}
If anyone knows any tutorial or something related that can help me improve this code because if one day I want to add another database I will have to duplicate the repositories then add one more conditional in each of my controllers.
I'm open to suggestions