使用ReactiveMongoRepository修改属性并保存无效果的问题求助
问题描述
在Mongock脚本中使用ReactiveMongoRepository修改MongoDB文档属性并保存,但执行后数据库无任何变更。尝试过doOnNext、flatMap等操作仍未解决,相关简化代码如下:
Repository
@Repository public interface CalendarMongoRepository extends ReactiveMongoRepository<CalendarMongo, CalendarMongoId> { //Some methods not used here }
POJO
@Document("calendars") public class CalendarMongo { @Id private CalendarMongoId id; private String calendar; public String getCalendar() { return calendar; } public CalendarMongo setCalendar(String calendar) { this.calendar = calendar; return this; } //Other getters setters and other attributes }
POJO ID
public class CalendarMongoId { @Indexed(name = "branchCode_index") private BranchEnum branchCode; //Getters setters and other attributes }
Mongock脚本
@Slf4j @ChangeUnit(id = "SetupAttribute", order = "7", author = "mongock") public class DatabaseChangeV007SetupAttribute { private final CalendarMongoRepository calendarMongoRepository; public DatabaseChangeV007SetupFieldType(CalendarMongoRepository calendarMongoRepository) { this.calendarMongoRepository = calendarMongoRepository; } @Execution public void migrationMethod() { calendarMongoRepository.findAll() .map(calendarMongo -> calendarMongo.setCalendar("AA")) .map(calendarMongoRepository::save); } @RollbackExecution public void rollback() { log.error("Rollback invoked"); } }
确认脚本结构无问题,但执行后数据库未更新,求解决办法。
问题原因与解决办法
核心原因
响应式编程中,Flux/Mono是惰性求值的,仅定义数据流不会触发执行,必须通过订阅(subscribe)启动整个数据流的处理。你的代码只构建了数据流,但没有触发订阅,因此实际未执行任何数据库操作。同时,save方法返回Mono<CalendarMongo>,用map处理会导致嵌套的响应式类型,无法正确执行保存逻辑。
修复后的脚本代码
@Execution public void migrationMethod() { calendarMongoRepository.findAll() .map(calendarMongo -> calendarMongo.setCalendar("AA")) .flatMap(calendarMongoRepository::save) // 用flatMap展开嵌套的Mono .doOnNext(updated -> log.info("Updated calendar with ID: {}", updated.getId())) // 可选:记录更新日志 .blockLast(); // 阻塞等待所有操作完成,适配Mongock同步执行环境 }
关键细节说明
- 用
flatMap替代map处理保存:calendarMongoRepository.save()返回Mono<CalendarMongo>,如果用map会将每个元素包装为Mono,形成Flux<Mono<CalendarMongo>>,无法正确执行保存。flatMap会展开嵌套的响应式类型,合并为Flux<CalendarMongo>,确保保存操作被正确执行。 - 触发订阅并等待完成:使用
blockLast()启动数据流并等待所有更新操作结束。由于Mongock的@Execution方法是同步执行的,blockLast()可以避免脚本提前退出导致操作未完成。如果仅用subscribe(),脚本会直接返回,可能在数据库操作完成前就结束,导致数据未更新。 - 日志辅助排查:添加
doOnNext记录更新后的文档ID,方便验证操作是否执行,也能在出现问题时快速定位异常点。
内容的提问来源于stack exchange,提问作者Nix
相关产品推荐
相关产品推荐

