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

无法将对象持久化到数据库:ID始终为null问题求助

问题根源与解决方案

核心问题:重复的JPA主键注解

你的DealModel类中同时在字段id和其getter方法getId()上标注了@Id和@GeneratedValue,这会导致JPA的映射策略冲突,无法正确识别主键生成规则,进而导致ID无法自动生成,甚至手动赋值也无效。

修复步骤

1. 移除重复的主键注解

保留字段上的注解,删除getter方法上的重复注解,修改后的DealModel主键部分代码如下:

@Entity
@Table(name = "deals")
public class DealModel { 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    // 删除getId()上的@Id和@GeneratedValue,保留原有方法
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    // 其他字段的getter/setter和构造函数保持不变
}

2. 验证数据库表结构

确认deals表的id字段是自增主键(如MySQL的AUTO_INCREMENT、PostgreSQL的IDENTITY),手动插入能成功说明这部分大概率没问题,但建议再核对一次表结构。

3. 检查事务配置

如果调用save()的方法不在事务上下文内,Spring Data JPA可能无法同步生成的ID。确保执行持久化的方法被@Transactional注解标记:

@Service
public class DealService {
    private final DealsRepository dealsRepository;

    public DealService(DealsRepository dealsRepository) {
        this.dealsRepository = dealsRepository;
    }

    @Transactional
    public DealModel saveDeal(DealModel dealModel) {
        return dealsRepository.save(dealModel);
    }
}

4. 避免手动干预自增ID

既然使用GenerationType.IDENTITY策略,就不要在构造函数里手动赋值id,这会干扰JPA的自增逻辑,让数据库自动生成ID即可。

额外优化建议

可以用Lombok的@Data注解简化代码,自动生成getter/setter,减少注解重复的概率:

@Data
@ToString
@Entity
@Table(name = "deals")
public class DealModel { 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @NotBlank(message = "Title is mandatory")
    private String title;
    @NotBlank(message = "Url is mandatory")
    private String url;
    private float price;

    public DealModel(String title, String url, float price){
        this.title=title;
        this.url = url;
        this.price= price;
    }

    public DealModel(){}
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:00:24