无法将对象持久化到数据库: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
相关产品推荐
相关产品推荐

