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

Spring Boot中MongoDB Long类型自增ID生成失败问题

解决Spring Data MongoDB中Long类型自增ID的问题

问题描述

在创建名为Pallet的MongoDB集合时,想要让Long类型的idPallet字段实现自增,但新增数据时总是抛出异常:

"message": "Cannot autogenerate id of type java.lang.Long for entity of type com.example.ShippingTest.collections.Pallet"

试过移除@SequenceGenerator注解,问题依然存在;添加@Entity注解后又出现新错误:'Basic' attribute type should not be a container,还要求再添加一个ID。

问题原因

Spring Data MongoDB不支持JPA的@GeneratedValue、@SequenceGenerator这类注解——这些是专为关系型数据库设计的。MongoDB默认用ObjectId作为主键,要实现Long类型的自增ID,得手动处理序列生成逻辑。

解决方案步骤

1. 初始化序列集合

先在MongoDB里创建一个专门存序列的集合(比如叫sequence),用来记录每个业务集合的当前自增值。可以手动插入初始数据:

{
  "_id": "pallet_seq",
  "seq": 0
}

2. 实现自增ID生成器

创建一个监听类,在Pallet数据插入前自动生成自增ID:

import org.springframework.data.mongodb.core.mapping.event.AbstractMongoEventListener;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

@Component
public class PalletIdGenerator extends AbstractMongoEventListener<Pallet> {

    private final MongoTemplate mongoTemplate;

    public PalletIdGenerator(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @Override
    public void onBeforeConvert(BeforeConvertEvent<Pallet> event) {
        Pallet pallet = event.getSource();
        // 只有当idPallet为空时才生成自增ID
        if (pallet.getIdPallet() == null) {
            pallet.setIdPallet(getNextSequence("pallet_seq"));
        }
    }

    // 获取下一个序列值
    private Long getNextSequence(String seqName) {
        Query query = new Query(Criteria.where("_id").is(seqName));
        Update update = new Update().inc("seq", 1);
        // 不存在则插入,返回更新后的文档
        FindAndModifyOptions options = new FindAndModifyOptions().returnNew(true).upsert(true);
        
        Sequence sequence = mongoTemplate.findAndModify(query, update, options, Sequence.class);
        return sequence.getSeq();
    }
}

同时创建对应序列集合的实体类:

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Document(collection = "sequence")
public class Sequence {
    @Id
    private String id;
    private Long seq;
}

3. 修改Pallet实体类

删掉所有JPA相关注解,只保留Spring Data MongoDB的注解:

package com.example.ShippingTest.collections;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "Pallet") // 指定MongoDB对应的集合名
public class Pallet {
    @Id
    private Long idPallet;
    private int maxPallet;
    private String typePallet;
    private String shipAddress;
    private String shipLocation;
    private String shipCountry;
    private String destination;
    private List<PS> PackingSlip;
}

4. 测试功能

现在调用POST接口/pallets新增Pallet数据,idPallet会自动从1开始递增,之前的异常也不会再出现了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 09:35:23