Spring Data JPA的save方法执行失败,实体字段全为null是什么原因?
问题根因
Controller参数注解冲突
你在单条保存的saveItem接口的Item参数上同时标注了@ModelAttribute和@RequestBody,两个注解的参数绑定逻辑完全冲突:@RequestBody的作用是读取HTTP请求体的JSON内容反序列化为对象,而@ModelAttribute是从URL查询参数、表单提交参数中绑定属性值,不会解析请求体的JSON。Spring MVC遇到两个注解同时存在时,会优先执行@ModelAttribute的绑定逻辑,你当前请求是JSON格式,没有对应的表单/查询参数,所以绑定出来的Item对象全部是默认值(数值类型为0,引用类型为null),和你日志里打印的空对象特征完全吻合。JSON字段与实体属性名不匹配
就算删除冲突的@ModelAttribute,还是会出现字段为null的问题:你的请求体里传的是item_name,但实体类的属性名是name,@Column(name="item_name")是JPA和数据库映射的注解,不会影响Jackson的JSON反序列化规则,Jackson默认按属性名匹配,所以item_name无法映射到name字段,导致name为空。
如果要保留请求体的item_name字段,需要在实体的name属性上加@JsonProperty("item_name")注解,或者修改请求体的字段为name。冗余配置(不影响功能):你实体类上同时加了
@Data和@Getter/@Setter,@Data已经包含了getter、setter、toString等注解,属于重复配置,可以删除冗余的@Getter@Setter。
修复方案
- 删除
saveItem接口Item参数上的@ModelAttribute("item"),调整后参数写法如下:
public ResponseEntity<?> saveItem(@Valid @RequestBody Item item, @RequestHeader("Authorization") String userToken)
- 调整JSON字段和实体属性的映射:要么修改请求体的
item_name为name,要么在实体name属性上加@JsonProperty("item_name"):
@Column(name="item_name") @NotBlank(message = "Name must not be empty") @JsonProperty("item_name") private String name;
内容的提问来源于stack exchange,提问作者Yurii

