如何避免Spring Boot MongoDB将自定义actor_id覆盖为自动生成的ObjectId
问题根因
你在Actor实体类中为actor_id字段添加了@Id注解,Spring Data MongoDB默认会将标注@Id的字段映射为MongoDB集合内置的_id主键字段。查询数据时,框架会直接把MongoDB自动生成的_id值赋值给该字段,覆盖数据库中实际存储的actor_id普通字段的值,就出现了你遇到的返回值异常问题。
解决方案
根据你的业务需求可以选择以下两种方案:
方案1:保留MongoDB自动生成的_id作为主键,actor_id作为独立业务字段
该方案适用于你已经有存量数据,MongoDB中已经存在自动生成的_id主键,actor_id是单独存储的业务字段的场景。
1. 修改Actor实体类
package com.film.SpringAplication.model; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Field; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Data; @Document(collection="actor") @AllArgsConstructor @Data public class Actor { // 专门映射MongoDB自动生成的_id主键 @Id private String id; // 映射数据库中实际存储的actor_id业务字段,JsonProperty保证接口返回的字段名是actor_id @Field("actor_id") @JsonProperty("actor_id") private String actorId; @Field("first_name") @JsonProperty("first_name") private String firstName; @Field("last_name") @JsonProperty("last_name") private String lastName; }
2. 扩展ActorRepository查询方法
package com.film.SpringAplication.repository; import org.springframework.data.mongodb.repository.MongoRepository; import com.film.SpringAplication.model.Actor; import java.util.List; public interface ActorRepository extends MongoRepository<Actor,String>{ // 新增按业务字段actorId查询的方法 List<Actor> findByActorId(String actorId); }
3. 修改ActorService对应方法
// 按业务actor_id查询的方法可以简化为直接调用Repository方法 public List<Actor> getActor(String actorId) { return actorRepository.findByActorId(actorId); } // 如果需要按业务actor_id删除,也需要对应修改删除逻辑 public String deleteActor(String actorId) { List<Actor> actors = actorRepository.findByActorId(actorId); actorRepository.deleteAll(actors); return "User deleted"; }
方案2:直接用actor_id作为MongoDB主键
该方案适用于actor_id本身就是业务唯一主键,不需要MongoDB额外生成主键的场景。
你不需要修改现有实体类的字段结构,只需要在插入数据时主动给actor_id赋值即可,保存后MongoDB的_id字段值就等于你传入的actor_id,查询时返回的actor_id就是你存储的业务值,不会再被自动生成的ObjectId覆盖。
内容的提问来源于stack exchange,提问作者Edmilson Almeida
相关产品推荐
相关产品推荐

