You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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同步执行环境
}

关键细节说明

  1. 用flatMap替代map处理保存:calendarMongoRepository.save()返回Mono<CalendarMongo>,如果用map会将每个元素包装为Mono,形成Flux<Mono<CalendarMongo>>,无法正确执行保存。flatMap会展开嵌套的响应式类型,合并为Flux<CalendarMongo>,确保保存操作被正确执行。
  2. 触发订阅并等待完成:使用blockLast()启动数据流并等待所有更新操作结束。由于Mongock的@Execution方法是同步执行的,blockLast()可以避免脚本提前退出导致操作未完成。如果仅用subscribe(),脚本会直接返回,可能在数据库操作完成前就结束,导致数据未更新。
  3. 日志辅助排查:添加doOnNext记录更新后的文档ID,方便验证操作是否执行,也能在出现问题时快速定位异常点。

内容的提问来源于stack exchange,提问作者Nix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:32:22