Spring Boot一对一关联保存触发PropertyValueException问题求助
解决Hibernate PropertyValueException:Publication.acessDate非空属性为null的问题
问题核心原因分析
- 日期格式不匹配导致字段解析为null:请求中
acessDate的格式是yyyy-MM-dd(如2004-02-03),但Publication实体中@DateTimeFormat指定的是dd/MM/yyyy,Spring无法正确解析日期字符串,导致acessDate被设置为null,触发非空约束错误。 - OneToOne关联的主键配置冲突:
Tcc实体同时使用@GeneratedValue和@MapsId,前者会让Hibernate自动生成主键,后者要求复用关联Publication的主键,两者冲突导致Hibernate处理实体状态时出现异常。
具体解决方案
1. 修正日期字段的格式注解
修改Publication实体中的日期字段,让注解匹配请求的日期格式,同时添加@JsonFormat处理JSON序列化/反序列化(@DateTimeFormat主要用于表单提交):
@Data @Entity public class Publication { // 其他字段不变 @Column(nullable = false) @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "UTC") private Date publicationDate; @Column(nullable = false) @DateTimeFormat(pattern = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd", timezone = "UTC") private Date acessDate; // 其他字段不变 }
2. 修正Tcc实体的主键配置
去掉Tcc实体中主键的@GeneratedValue注解,因为@MapsId会将关联Publication的主键作为自身主键,无需自动生成:
@Data @Entity public class Tcc { @Id private Long idTcc; // 与Publication的idPublica类型保持一致 @Column(length = 100, nullable = false) private String degree; @Column(length = 100, nullable = false) private String course; @MapsId @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "publica_id", referencedColumnName = "idPublica") private Publication publication; }
3. 优化服务层保存逻辑
无需重复查询已保存的Publication,直接使用保存后的持久化实例关联Tcc即可:
@Autowired private TccRepository tccRepo; @Autowired private PublicacaoService pubServ; public Tcc saveTcc(Tcc tcc) throws RelationTypeNotFoundException { // 保存Publication,获取持久化状态的实例 Publication savedPub = pubServ.savePub(tcc.getPublication()); // 直接关联到Tcc tcc.setPublication(savedPub); // 保存Tcc,@MapsId会自动将savedPub的id赋值给tcc的idTcc return tccRepo.save(tcc); }
验证要点
- 确保请求中的日期格式与实体注解的格式完全匹配,避免解析失败。
- 检查数据库中
Publication表的acessDate字段确实设置为非空约束,避免配置与数据库不一致。
内容的提问来源于stack exchange,提问作者lys_18
相关产品推荐
相关产品推荐

