-
Notifications
You must be signed in to change notification settings - Fork 700
Description
what's the issue
On my project I've configured multiple datasources through spring data (e.g., Gcp Datastore and ElasticSearch), including multiple Repository beans, but this could be any other datasources (e.g., PostgreSQL, Moongodb ...), and I configured a jackson repository populator (code below).
@Bean
fun populator(objectMapper: ObjectMapper): Jackson2RepositoryPopulatorFactoryBean = Jackson2RepositoryPopulatorFactoryBean().apply {
setMapper(objectMapper)
setResources(
arrayOf(
ClassPathResource("data/partners.json")
)
)
}
@Repository
interface PartnersDatastoreRepository: DatastoreRepository<PartnerEntity, String>
@Repository
interface PartnersOpensearchRepository: ElasticsearchRepository<PartnerEntity, String>
@Repository
interface PartnersSpannerRepository : SpannerRepository<PartnerEntity, String>And I was expecting the populator to populate data on all of my datasources, however only one is populated.
Where this issue might be coming from 🤔
I've debugged a bit to figure out from where this is coming, and I found it's happening here org.springframework.data.repository.support.Repositories#cacheRepositoryFactory.
Inside this method, the logic for caching repositories is controlled by cacheFirstOrPrimary.
This implementation only retains the first or primary repository associated with a given entity type.
All other repositories for the same entity are silently ignored, even though Spring correctly detects all of them during the scan.
As a result:
- The populator sees only one repository per domain type, even if they are for multiple backing datasources (jpa, mongodb ...).
- Seed data is only inserted into a single datasource.
- There is no way to instruct the populator to target multiple backing stores.
suggested fix: it would be better to store multiple repositories in repositoryBeanNames rather than only one.
workaround
Currenlty I did NOT find a way to populate all of my datasource, but I can at least target one by annotating its relevant repository with Primary