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

Spring Boot 3.0.5中ReactiveMongoTemplate更新抛出DuplicateKeyException

解决Spring Boot 3.0.5中MongoDB更新Post时的重复键异常

问题根源

你在Post类的comments字段上使用了@DocumentReference注解,这个注解用于建立MongoDB文档间的引用关系(类似关系型数据库的外键),该字段应存储Comment文档的_id值,而非完整的Comment实体。但你在addComment方法中,直接将插入后的完整Comment对象push到comments数组中,导致MongoDB尝试把包含自身_id的Comment对象存入Post的comments数组。后续操作时,Spring Data MongoDB会误将这个内嵌的Comment识别为需要独立保存的新实体,从而触发重复键错误(该Comment的_id已存在于comments集合中)。

修正方案

不需要让Post类实现Persistable接口,只需修改addComment方法,仅将Comment的id推送到Post的comments数组中:

@Override
public Mono<Boolean> addComment(String id, String content) {
    return mongoTemplate.insert(Comment.builder().content(content).build())
            .flatMap(c -> mongoTemplate.update(Post.class)
                    .matching(where("id").is(id))
                    .apply(new Update().push("comments").value(c.getId()))
                    .first()
                    .hasElement()
            );
}

额外说明

如果你的业务需求是将Comment作为内嵌文档直接存储在Post的comments数组中(而非文档引用),直接移除comments字段上的@DocumentReference注解即可。此时完整的Comment对象会内嵌到Post文档里,不会出现引用相关的重复键问题。两种存储模式的选择取决于业务场景:

  • 文档引用:适合Comment需要被多个Post共享,或需要独立查询、更新Comment的场景
  • 内嵌文档:适合Comment仅属于某个Post,不需要独立操作的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:43:15