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

Spring Boot集成MongoDB新增商品时覆盖原有旧商品问题求助

问题原因

  • 新增时主动传入了固定id:你在ProductoServicioImplement的addProducto方法中创建Producto实例时,第一个参数传了Integer.SIZE,这是Java Integer类的固定常量(值为32),每次新增商品的id都被写死为32。MongoRepository的save()逻辑是:如果传入的实体id已存在则执行更新操作,不存在才执行插入,因此每次新增都会覆盖id为32的原有商品。
  • 主键生成逻辑不兼容MongoDB:@GeneratedValue(strategy = GenerationType.AUTO)是JPA用于关系型数据库的主键生成注解,对MongoDB不生效,你使用Integer类型作为Mongo主键,又没有配置对应的自增生成逻辑,无法自动生成唯一主键。
  • 注解混用冲突:你同时给实体类加了JPA的@Entity、@Table和MongoDB的@Document注解,主键字段同时标注了Spring Data Mongo的@org.springframework.data.annotation.Id和JPA的@javax.persistence.Id,注解冲突也会导致主键处理异常。

修复方案

1. 修改新增商品的id赋值逻辑

首先给Producto实体类新增不带id的构造方法,新增商品时不要主动赋值id:

// Producto类新增构造方法
public Producto(String stockc, String nom, String cod, Double prec,categoriaProducto cgprod){
    this.stock = stockc;
    this.nombre = nom;
    this.codigo = cod;
    this.precio= prec;
    this.categoriaproducto=cgprod;
}

// 修改Service中的addProducto方法,删除固定id的传参
@Override
public void addProducto(String stock, String nombre, String codigo, Double precio , categoriaProducto categoriaproducto) {
    Producto p = new Producto(stock, nombre, codigo, precio, categoriaproducto);
    productosRepository.save(p);
}

2. 修正实体类注解和主键类型

如果项目确定使用MongoDB,移除所有JPA相关的注解,主键建议直接用Mongo默认的ObjectId类型,天然唯一无需自行处理自增逻辑:

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.bson.types.ObjectId;
import java.io.Serializable;

@Document(collection = "productos")
public class Producto implements Serializable {
    @Id
    private ObjectId id;
    // 其余字段保持不变,同步修改getter、setter和对应构造方法的id类型即可
}

3. 若必须使用Integer作为主键

需要自行实现MongoDB自增主键逻辑:新增一个专门存储自增序列的集合,每次新增商品前先查询序列值累加后作为主键使用。

额外提醒:现有代码中的getProductoById方法逻辑错误,直接new了空的Producto实例没有查询数据库,后续用到该方法时需要修正为调用Repository的findById查询返回结果。

内容的提问来源于stack exchange,提问作者José d.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 04:00:04