SpringBoot向PostgreSQL提交POST请求插入值为NULL的问题
问题排查:POST请求新增客户时字段插入为NULL
问题描述
构建包含三个关联PostgreSQL表的Web应用,通过REST API管理数据,但执行POST请求新增客户时,数据库中所有非ID字段均被插入为NULL。
相关代码及请求、结果如下:
Customer.java
@NoArgsConstructor @AllArgsConstructor @Getter @Setter @NonNull @Table(name = "customers") @Entity public class Customer implements Serializable { private @Id @Column(name = "customerid") @GeneratedValue(strategy = GenerationType.IDENTITY) Long id; @Column(name = "customer_name") private String customerName; @Column(name = "customer_surname") private String customerSurname; }
CustomerController.java(核心POST方法)
@PostMapping public Long add(@RequestBody Customer c) { return this.customerService.add(c); }
POST请求示例
curl http://localhost:8080/customers -X POST -d '{"customer_name": "John","customer_surname": "Smith"}' -H 'Content-Type: application/json'
数据库插入结果
select * from customers where customerid = 1 ------------------------------------------------ |customerid | customer_name | customer_surname | ----------------------------------------------- | 1 | NULL | NULL | ------------------------------------------------
原因分析
- JSON字段与实体类属性映射不匹配:请求中使用下划线命名的
customer_name、customer_surname,但实体类属性是驼峰命名的customerName、customerSurname。Spring默认使用的Jackson序列化框架,默认规则是将JSON字段与实体类属性的命名格式直接匹配,因此无法将请求中的下划线字段映射到实体类的驼峰属性,导致属性值为NULL。 - @NonNull注解使用错误:将Lombok的
@NonNull注解放在类上,这并非该注解的正确用法(@NonNull应作用于字段或构造方法参数),虽不会直接导致字段为NULL,但会造成代码混淆,无实际作用。
解决方案
方案1:修改请求JSON字段为驼峰格式
直接调整POST请求中的字段名,与实体类属性的驼峰命名保持一致:
curl http://localhost:8080/customers -X POST -d '{"customerName": "John","customerSurname": "Smith"}' -H 'Content-Type: application/json'
方案2:为实体类字段添加@JsonProperty注解
通过@JsonProperty指定JSON字段名与实体类属性的映射关系,无需修改请求:
@NoArgsConstructor @AllArgsConstructor @Getter @Setter @Table(name = "customers") @Entity public class Customer implements Serializable { @Id @Column(name = "customerid") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "customer_name") @JsonProperty("customer_name") private String customerName; @Column(name = "customer_surname") @JsonProperty("customer_surname") private String customerSurname; }
同时移除类上的@NonNull注解,避免代码混淆。
方案3:全局配置Jackson自动转换下划线与驼峰
在Spring Boot配置文件中添加全局配置,让Jackson自动将下划线命名的JSON字段转换为驼峰命名的实体类属性:
- application.properties:
spring.jackson.property-naming-strategy=SNAKE_CASE
- application.yml:
spring: jackson: property-naming-strategy: SNAKE_CASE
该方案无需修改请求或实体类代码,适合需要统一处理下划线与驼峰映射的场景。
内容的提问来源于stack exchange,提问作者sf99sL
相关产品推荐
相关产品推荐

