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

Spring中保存Machine实体因ID为空报错,User却正常的原因咨询

问题分析与解决

问题描述

使用Java Spring开发应用时,定义了User和Machine两个实体,代码如下:

User实体代码

@Getter
@Setter
@Entity
@Table
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @NotNull
    private Long id;

    // etc.
}

Machine实体代码

@Getter
@Setter
@Entity
@Table
public class Machine {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @NotNull
    private Long id;

    @ManyToOne
    @JoinColumn(name = "created_by")
    @NotNull
    private User createdBy;
}

保存新User时不传入ID可成功保存,但保存新Machine时不传入ID会触发验证失败,报错信息翻译为:

ConstraintViolationImpl{插值消息='不能为空', 属性路径=id, 根Bean类=class raf.edu.rs.nwpbackend.model.Machine, 消息模板='{javax.validation.constraints.NotNull.message}'}

传入ID或移除@NotNull注解则可成功保存,二者配置相同且保存方式一致,询问原因。

原因解析

  1. @NotNull与IDENTITY生成策略的逻辑冲突:
    当使用GenerationType.IDENTITY生成策略时,实体ID的值是由数据库在插入操作时自动生成的,插入前实体的ID字段值为null。但@NotNull注解会触发Bean Validation(JSR-380)的非空校验,这本身就和IDENTITY策略的运作逻辑矛盾。

  2. 两个实体的验证触发差异:

    • User实体没有关联其他带@NotNull约束的字段,Spring Data JPA或Hibernate在保存时可能绕过了完整的Bean Validation流程,导致ID字段的@NotNull约束未被触发。
    • Machine实体存在@ManyToOne关联的@NotNull字段createdBy,这个字段的校验触发了完整的Bean Validation,此时ID字段的@NotNull约束也被检查到,因值为null而触发报错。

解决办法

直接移除@Id字段上的@NotNull注解即可。因为IDENTITY策略下,数据库会保证ID非空且自增,无需通过Bean Validation提前校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 08:50:46