Spring JPA Hibernate @OneToMany父实体如何增删改子实体并解决级联异常
修正方案
- 第一步:删除
SubIngredientKey嵌入式主键中两个@ManyToOne注解的cascade = CascadeType.ALL配置。Ingredient是独立业务实体,不需要通过关联表的主键级联操作,这是栈溢出的核心诱因。
修正后的SubIngredientKey代码:
@Embeddable public class SubIngredientKey implements Serializable{ @ManyToOne private Ingredient ingredientId; @ManyToOne private Ingredient subIngredientId; // 原有getter、setter保持不变 }
- 第二步:调整
Ingredient实体中subIngredients属性的级联配置,保留全操作级联同时开启孤儿删除:
修正后的@OneToMany配置:
@OneToMany(mappedBy = "embId.ingredientId", fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE}, orphanRemoval = true) private Set<SubIngredient> subIngredients = new HashSet<SubIngredient>();
- 第三步:操作
subIngredients列表时注意维护关联关系,新增SubIngredient实例时必须手动给embId的两个属性赋值:
// 示例操作代码 SubIngredient sub = new SubIngredient(); sub.getEmbId().setIngredientId(parentIngredient); // 绑定父原料 sub.getEmbId().setSubIngredientId(childIngredient); // 绑定子原料 sub.setQuantity(100); parentIngredient.getSubIngredients().add(sub); // 直接保存parentIngredient即可完成子实体持久化 ingredientRepository.save(parentIngredient);
原错误原因解释
- 栈溢出错误:
SubIngredientKey中两个@ManyToOne的全级联配置和Ingredient的@OneToMany全级联形成循环级联链,保存时互相触发级联操作,最终导致栈内存耗尽。 EntityNotFoundException错误:仅配置CascadeType.PERSIST的情况下,更新父实体时不会触发子实体的merge级联,JPA会尝试查询不存在的子实体记录,抛出找不到实体的异常。
内容的提问来源于stack exchange,提问作者Imad Che
相关产品推荐
相关产品推荐

