Spring Boot @OneToOne关联调用save时先删后插,如何改为单条update语句实现更新
问题解决方案
- 修正字段拼写错误
Student实体类中的关联字段名studenttClub多写了一个t,修正为studentClub,和StudentClub实体中的关联属性名保持一致,避免关联映射失效。 - 调整JoinColumn配置
StudentClub实体类作为双向关联的维护端,@JoinColumn注解需要去掉insertable = false, updatable = false配置,获得外键的写入和更新权限,同时可以移除不必要的CascadeType.ALL避免循环级联:
@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "student_id") private Student student;
- 给StudentClub配置独立主键
你遇到的先删后插核心原因大概率是StudentClub使用了club_code + student_id作为联合主键,修改club_code相当于修改主键字段,Hibernate不支持主键更新,只能删除原有数据再插入新数据。给StudentClub添加独立的自增主键作为唯一主键,club_code作为普通业务字段即可:
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // club_code作为普通业务字段 private String clubCode;
- 调整更新操作逻辑
更新时不要直接new新的StudentClub对象替换Student中的关联属性,orphanRemoval = true会识别为旧对象被丢弃,触发删除操作。正确操作流程:
- 调用Repository查询出需要更新的Student持久化对象
- 调用
getStudentClub()获取已关联的持久化StudentClub对象 - 直接调用set方法修改该对象的
clubCode属性 - 调用StudentRepository的save方法保存Student对象
- 可选优化配置
如果不需要自动删除丢弃的StudentClub对象,可以去掉Student侧@OneToOne注解中的orphanRemoval = true配置,避免误触发删除逻辑。
内容的提问来源于stack exchange,提问作者Capmu
相关产品推荐
相关产品推荐

