为何更新MariaDB记录后JPA会删除OneToMany关联的首个元素?
这个问题的核心原因在于**RegulationDepartment实体缺少了@JsonIdentityInfo注解**,而另外两个关联实体(Regulation和RegulationEntity)都配置了这个注解,导致Jackson在序列化/反序列化双向关联对象时出现异常,最终触发了JPA的orphanRemoval=true机制误删首个元素。
解决方案:给RegulationDepartment添加@JsonIdentityInfo注解
修改RegulationDepartment实体类,加上和另外两个实体一致的@JsonIdentityInfo配置:
@Entity @Table( name= "regulation_department") @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id") public class RegulationDepartment { @Override public String toString() { return "RegulationDepartment [id=" + id + ", department=" + department + "]"; } @Id @Column(name = "ID_REGULATION_DEPARTMENT") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NotNull @Column(name = "id_department") private Long department; @ManyToOne(fetch = FetchType.LAZY, cascade=CascadeType.ALL) @JoinColumn(name = "FK_ID_REGULATION", referencedColumnName="ID_REGULATION") private Regulation regulationDepartment; }
原因解释
在双向一对多关联中,当使用Jackson处理实体的序列化/反序列化时,如果没有@JsonIdentityInfo注解,会陷入循环引用的问题(Regulation包含RegulationDepartment列表,而每个RegulationDepartment又引用回Regulation)。这种情况下,Jackson会对实体的关联状态进行篡改,导致JPA在执行clear()和addAll()操作后,误判第一个RegulationDepartment对象已经脱离了父实体Regulation的关联。
因为你配置了orphanRemoval=true,JPA会自动删除被判定为"孤儿"的关联实体,这就是为什么首个RegulationDepartment记录被删除的原因。而RegulationEntity因为正确配置了@JsonIdentityInfo,Jackson能正确处理关联关系,所以没有出现这个问题。
额外验证建议
修改后重新执行更新操作,观察JPA的SQL日志,确认不会再出现delete from regulation_department的误删语句,同时检查数据库中的记录是否和预期一致。
内容的提问来源于stack exchange,提问作者Carlos Rivera Rafael

