Spring Boot MongoRepository调用findById/deleteById出现映射报错
问题原因
核心错误出在Post实体类的主键字段命名不规范:你定义的主键字段是private String Id;(首字母I大写),不符合Java小驼峰命名规则,导致Spring Data MongoDB的QueryMapper无法正确将实体主键字段和MongoDB默认的_id主键字段做绑定,在执行按ID查询、按ID删除这类需要用到主键条件的操作时,就会抛出映射错误。
你之前自定义@Query的写法也存在问题:MongoDB默认主键的存储字段名是_id,你写的查询条件{ 'id' : ?0 }匹配的是集合中普通的id字段,而非主键字段,自然无法查到正确结果。findAll()方法能正常执行是因为全量查询不需要构造主键查询条件,不会触发主键映射逻辑,所以没有暴露这个问题。
修复方案
按以下步骤修改即可解决问题:
- 修正实体类主键字段命名,将大写开头的
Id改为小驼峰格式的id,修正后的实体类代码如下:
@Document("posts") @Data @AllArgsConstructor @NoArgsConstructor public class Post { @Id private String id; // 字段名首字母改为小写 private Integer userId; private String content; private Integer likes; private Integer dislikes; }
- 删除你在
PostRepository中自定义重写的findById方法,Spring Data MongoDB内置的findById、deleteById方法会自动完成入参ID到_id字段的映射,不需要额外自定义。如果确实需要保留自定义主键查询,必须将查询条件中的字段名改为_id,正确写法如下:
@Override @Query("{ '_id' : ?0 }") Optional<Post> findById(String s);
提示:如果修改代码前你已经通过错误的实体类向MongoDB写入过数据,posts集合里的文档可能会同时存在
_id和冗余的id字段,需要先清理这类历史脏数据,避免后续出现字段映射冲突。
验证
修改完成后重启服务,再调用localhost:9192/posts/62a76719145e644e5b640327的GET、DELETE接口,就不会再出现映射报错,可正常查询、删除对应文档。
内容的提问来源于stack exchange,提问作者SnowKid
相关产品推荐
相关产品推荐

