Spring JPA保存实体到H2报not-null属性引用空值异常
问题根因
抛出非空约束异常的核心原因是传入持久层的Produto对象nome字段实际为null,和请求体传了nome参数的预期不符,问题出在实体类定义上:
你当前编写的Produto类只定义了私有字段,缺失两个必要部分:
- JPA规范明确要求所有实体类必须提供public/protected权限的无参构造方法,否则Hibernate无法正常实例化实体
- Spring默认使用Jackson完成JSON反序列化,把请求体JSON转成
Produto对象时,需要调用字段对应的setter方法完成属性注入,没有setter的话字段会保持默认值null
最终传到produtoRepository.save()方法的对象nome属性为null,触发了@Column(nullable = false)配置的非空约束,就抛出了对应的DataIntegrityViolationException嵌套PropertyValueException异常。
解决方案
二选一即可解决问题:
方案1:手动补全实体类必要方法
给Produto.java补全无参构造、所有字段的getter/setter方法,修改后代码如下:
@Entity public class Produto { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String nome; // JPA要求的无参构造 public Produto() {} // 字段getter、setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNome() { return nome; } public void setNome(String nome) { this.nome = nome; } }
方案2:用Lombok简化代码
如果项目已经引入Lombok依赖,直接在类上添加@Data注解即可,注解会自动编译生成无参构造、getter、setter、toString等通用方法,大幅简化样板代码:
import lombok.Data; import jakarta.persistence.*; @Data @Entity public class Produto { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String nome; }
注意:使用Lombok需要提前给VS Code安装Lombok支持插件,否则会出现编译找不到方法的问题。
修改完成后重启Spring Boot服务,再发送相同的POST请求即可正常将Produto数据写入H2数据库。
内容的提问来源于stack exchange,提问作者Victor Bittencourt
相关产品推荐
相关产品推荐

