sql - 休眠:一对多关系的级联删除问题
问题描述
我有以下实体模型。
@Entity
@Table(name="product")
public class ProductEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
...
@OneToMany(mappedBy = "productEntity", cascade = CascadeType.ALL)
private List<ProductAddonEntity> productAddonEntities;
}
@Entity
@Table(name="product_addon")
public class ProductAddonEntity {
@Id
@GeneratedValue(generator = "uuid2")
@GenericGenerator(name = "uuid2", strategy = "uuid2")
private UUID id;
...
@ManyToOne()
@JoinColumn(name = "addon_id")
private ProductEntity addonEntity;
}
我想删除产品,并且该删除还应删除与该产品相关的所有 ProductAddon 实体。所以我声明了与所有级联类型的一对多关系。但是当我尝试删除某些产品时,Hibernate 一开始会尝试在 product_addon 表中设置 null addon_id。但是该列具有非空约束,因此删除失败。
所以我添加到注释@ManyToOne 参数
@JoinColumn(name = "addon_id", nullable = false, updatable = false)
但是现在休眠只是尝试删除产品,然后再删除与该产品相关的 product_addon 实体。由于外键约束,此删除失败(无法删除或更新父行:外键约束失败)。
这里有什么问题?此应用程序还使用 liquibase,因此外键不是由 hibernate 生成的。例如,addon_id 的外键没有删除操作,但我认为休眠不需要这些操作,因为它适用于更高的数据层
解决方案
孤儿删除是一种激进的删除级联模式,用于在需要删除父对象时删除子对象(@OneToOne 和 @OneToMany 关系)。此功能从 JPA 2.0 版本添加。JPA 删除操作
两种设置之间的区别在于对断开关系的响应。例如,当将地址字段设置为空或另一个地址对象时。
@Entity
class Employee {
@OneToOne(cascade=CascadeType.REMOVE)
private Address address;
}
如果仅指定了 cascade=CascadeType.REMOVE,则不会采取自动操作,因为断开关系不是删除操作。
@Entity
class Employee {
@OneToOne(orphanRemoval=true)
private Address address;
}
如果指定了 orphanRemoval=true,则断开连接的 Address 实例将被自动删除。这对于清理在没有来自所有者对象(例如 Employee)的情况下不应该存在的依赖对象(例如地址)很有用。
推荐阅读
- mysql - 是否可以将数据从 MS access VB 同步到 mysql 数据库
- javascript - 我的 JavaScript 函数没有使用我需要的变量之一
- com - WebAssembly:访问 COM 对象
- jekyll - Jekyll,Liquid:使用 `default: "...", allow_false: true` 会引发错误
- amazon-web-services - 使用 terraform 创建云端分发时出错。无效的查看器证书
- c++ - shared_ptr refcounter 实现 thead 安全
- reactjs - 如何通过在 react js 中使用异步获取将历史推送到特定组件
- regex - 正则表达式从字符串列中提取鞋码
- c++ - 在特定位置插入字符
- shell - tmux 的 vi 复制模式下的多个复制缓冲区