I've got a MongoDB collection with the following document structure:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Document
public class CustomerRouteManagementReportDocument implements TransactionDocument {
@Id
private String id;
@Indexed(unique = true)
private String customerId;
// ... other properties
private List<RouteHistoryEvent> routeHistoryEvents;
// ... other properties
}
Essentially, the following method should perform a bulk upsert: if a matching entry is found, it should append the first item from the routeHistoryEvents item into the existing document' routeHistoryEvents array. Otherwise, a whole new CustomerRouteManagementReportDocument should be inserted into the collection.
@Service
@Slf4j
public class CustomerRouteManagementReportRepositoryAdapter extends AbstractRepositoryAdapter<CustomerRouteManagementReport, CustomerRouteManagementReportDocument, CustomerRouteManagementReportDataRepository> implements CustomerRouteManagementReportRepository {
private final MongoTemplate mongoTemplate;
@Autowired
public CustomerRouteManagementReportRepositoryAdapter(ModelMapper mapper, CustomerRouteManagementReportDataRepository repository, MongoTemplate mongoTemplate) {
super(mapper, repository, CustomerRouteManagementReport.class, CustomerRouteManagementReportDocument.class);
this.mongoTemplate = mongoTemplate;
}
//... other methods
@Override
public Integer upsertTall(List<CustomerRouteManagementReportDocument> customerRouteManagementReports) {
BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, CustomerRouteManagementReportDocument.class);
try {
List<Pair<Query, Update>> updates = new ArrayList<>();
customerRouteManagementReports.stream().forEach(customerRouteManagementReport -> {
Query query = Query.query(Criteria.where("customerId").is(customerRouteManagementReport.getCustomerId()));
Update update = new Update();
update.addToSet("routeHistoryEvents").value(customerRouteManagementReport.getRouteHistoryEvents().get(0));
updates.add(Pair.of(query, update));
});
bulkOps.upsert(updates);
BulkWriteResult result = bulkOps.execute();
log.info("== BULK RESULT: {}, INSERTED: {}", result, result.getInsertedCount());
return result.getInsertedCount();
}
catch (Exception e) {
log.error("ERROR {}: IN UPSERTION {}", e.getClass().toGenericString(), e.getMessage());
return 0;
}
}
}
The problem is that no updates nor insertions are being made and no exception is raised either. I've tried with both an empty collection and a collection loaded with documents that will meet the query condition and should be updated, but my log simply reads:
== BULK RESULT: AcknowledgedBulkWriteResult{insertedCount=0, matchedCount=4, removedCount=0, modifiedCount=4, upserts=[]}, INSERTED: 0
However, in debugging, the method is called and it shows the appropriate number of Pairs for the number of objects that the usecase receives to process:

No MongoTemplate logs are issued (not even for the find operation that, I presume, it must perform in order to update my collection) which leads me to think that maybe my class doesn't have a proper MongoTemplate configured. However, there are no connection errors thrown either. This is our config class for MongoDB:
@Configuration
@ConditionalOnProperty(name = "spring.data.mongodb.uri-report")
@EnableReactiveMongoRepositories(basePackages = "package name",
reactiveMongoTemplateRef = ReportMongoConfig.REPORT_REACTIVE_MONGO_TEMPLATE)
public class ReportMongoConfig {
protected static final String REPORT_REACTIVE_MONGO_TEMPLATE = "reportReactiveMongoTemplate";
@Value("${spring.data.mongodb.uri-report}")
private String connectionStringReport;
@Bean
public ConnectionString getConnectionDataBaseReport() {
return new ConnectionString(connectionStringReport);
}
@Bean
public ReactiveMongoTemplate reportReactiveMongoTemplate(MappingMongoConverter mappingMongoConverter) {
return new ReactiveMongoTemplate(reactiveReportMongoDatabaseFactory(getConnectionDataBaseReport()), mappingMongoConverter);
}
@Bean
public MongoTemplate mongoTemplate(MappingMongoConverter mappingMongoConverter) {
return new MongoTemplate(reportMongoDBFactory(getConnectionDataBaseReport()), mappingMongoConverter);
}
@Bean
public ReactiveMongoDatabaseFactory reactiveReportMongoDatabaseFactory(ConnectionString getConnectionDataBaseExperience) {
return new SimpleReactiveMongoDatabaseFactory(getConnectionDataBaseExperience);
}
@Bean
public MongoDbFactory reportMongoDBFactory(ConnectionString connectionString) {
return new SimpleMongoClientDbFactory(connectionString);
}
}
I'm wondering if there's an injection issue when providing the appropriate MongoTemplate bean to the repository class or if there's an issue with the queries built inside the upsertAll method.
It turned out that somewhere else in a the application there's another
MongoTemplatebean connected to a different collection. Organizing the beans using@Primaryand@Qualifiersolved the issue.