Spring JPA提交Entrants实体时userid与eventid字段存库为null问题求助
问题根因
你遇到的userid、eventid字段为null的问题由两个原因导致:
- 字段名不匹配:你在Postman中提交的请求字段是
user_id、event_id,但Entrants实体中对应的属性名是userid、eventid,Spring MVC默认的Jackson反序列化工具找不到对应字段,不会赋值。 - 类型不匹配:
Entrants实体中的userid是User类型、eventid是Event类型,Jackson默认不会自动把你传入的数字ID转换为对应的JPA实体对象。
推荐解决方案
生产环境不要直接使用JPA实体作为HTTP接口的入参,建议新增DTO(数据传输对象)接收请求参数,再组装为实体对象存储。
步骤1:新增请求接收DTO
@Data public class EntrantRequest { private Long userId; private Long eventId; }
步骤2:调整控制器逻辑
先根据请求传入的ID查询对应的User和Event实体,再组装为Entrants对象保存:
@PostMapping("/management/events/entrants") GenericResponse createEntrant(@Valid @RequestBody EntrantRequest request) { // 根据ID查询用户,不存在则抛出异常 User user = userRepository.findById(request.getUserId()) .orElseThrow(() -> new RuntimeException("对应ID的用户不存在")); // 根据ID查询活动,不存在则抛出异常 Event event = eventRepository.findById(request.getEventId()) .orElseThrow(() -> new RuntimeException("对应ID的活动不存在")); // 组装参与者实体 Entrants entrant = new Entrants(); entrant.setUserid(user); entrant.setEventid(event); // 保存到数据库 entrantService.save(entrant); return new GenericResponse("Entrant saved"); }
步骤3:调整Postman请求体
和DTO字段名保持一致即可:
{ "userId": 1, "eventId": 1 }
临时快速验证方案(不推荐生产环境使用)
如果只是本地快速验证功能,不想做DTO改造,可以通过添加Jackson注解实现直接按ID反序列化实体:
- 给
User、Event实体添加反序列化配置:
// User实体类上加注解 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class User implements UserDetails, Serializable { // 原有逻辑保持不变 } // Event实体类上加注解 @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class Event implements Serializable { // 原有逻辑保持不变 }
- 给
Entrants实体的关联字段添加字段映射注解:
@Entity @Data @NoArgsConstructor @AllArgsConstructor public class Entrants implements Serializable { @Id @GeneratedValue Long id; @ManyToOne @JoinColumn(name = "user_id") @JsonProperty("user_id") // 和请求字段名匹配 User userid; @ManyToOne @JoinColumn(name = "event_id") @JsonProperty("event_id") // 和请求字段名匹配 Event eventid; }
调整后直接使用你原来的请求体即可完成参数接收。
内容的提问来源于stack exchange,提问作者James Smith
相关产品推荐
相关产品推荐

