Closed spring-projects-issues closed 2 years ago
nerg4l commented
Can this be added to the the documentation for Spring Data MongoDB - Section 8.8.3. Repository Populators and Spring Data R2DBC - Section 11.8.3. Repository Populators? It surprised me when I switched from MongoRepository to ReactiveMongoRepository and Jackson2RepositoryPopulatorFactoryBean stopped working all of a sudden
After stepping through the code - and watching the org.springframework.data.repository.support.ReflectionRepositoryInvoker
manage to locate the .save
method on the reactive mongo repo - but then fail to subscribe to the resulting mono/result it makes sense that the operations are never committed.
protected RepositoryInvoker createInvoker(RepositoryInformation information, Object repository) {
if (repository instanceof PagingAndSortingRepository) {
return new PagingAndSortingRepositoryInvoker((PagingAndSortingRepository<Object, Object>) repository, information,
conversionService);
} else if (repository instanceof CrudRepository) {
return new CrudRepositoryInvoker((CrudRepository<Object, Object>) repository, information, conversionService);
} else {
return new ReflectionRepositoryInvoker(repository, information, conversionService);
}
}
Perhaps a check for instanceof ReactiveSortingRepository
where the return is a new, sub-class of the ReflectionRepositoryInvoker
, ReflectionReactiveRepositoryInvoker
- where that invoker calls the terminal method on the Mono<> returned from the save method(s)?
This took me by surprise as well and cost me quite a few minutes to figure this out. Seemingly for a very long time the populator just doesn't work with reactive repositories.
Hello, I'm working on a fix, see my pull request #2543
Related #2558
We worked around this in a service we use for mock data:
@Configuration
@EnableReactiveMongoRepositories(basePackages = "com.company.api.mock.repository")
@Slf4j
class MongoConfiguration {
@Value("classpath:personas/*.json")
Resource[] resources
@Autowired
AccountRepository repository
/**
*
* @param objectMapper
* @return Disposable
*
* This is a hacky way to seed mongodb with some data from json files. Usually we
* should use Jackson2RepositoryPopulatorFactoryBean, but it doesn't work with reactive
* mongodb repositories.
*/
@Bean
Disposable populator(ObjectMapper objectMapper) {
Flux.just(resources)
.flatMap({
def json = new String(it.inputStream.readAllBytes())
def accounts = objectMapper.readValue(json, Account[])
repository.saveAll(accounts.toList())
})
.subscribe() // shouldn't need to do this but not sure what the right way is
}
}
Superseded by #2558
Juergen Zimmermann opened DATACMNS-1133 and commented
We finally migrated our microservices to Spring Cloud Finchley.M1, Spring Boot 2.0.M3, Spring Security 5.0.0.M3, and Spring Data Kay.RC2.All Repos are reactive. However, in our "dev" profile we we are populating a MongoDB database via Jackson2RepositoryPopulatorFactoryBean. Just for this purpose we still have to define (synchroneous) CrudRepositories. Therefore, we would appreciate if Jackson2RepositoryPopulatorFactoryBean could use our ReactiveCrudRepositories
Affects: 2.0 RC2 (Kay)
1 votes, 2 watchers