java - 使用 orphanRemoval Spring JPA 自动删除子实体
问题描述
目前,我有以下 2 个具有一对多关系的实体 -
@Data
@Entity
@Table(name = "invoice_line")
@IdClass(InvoiceLinePK.class)
public class InvoiceLineEntity {
@Id
@Column(name = "line_id")
private String lineId;
@Id
@Column(name = "client_id")
private Integer clientId;
@Id
@Column(name = "invoice_id")
private String invoiceId;
@Column(name = "item_id")
private String itemId;
@Column(name = "amount")
private BigDecimal amount;
@ManyToOne
private InvoiceEntity invoice;
}
@Entity
@Table(name = "invoice")
@IdClass(InvoicePK.class)
@Data
public class InvoiceEntity {
@Id
@Column(name = "client_id")
private Integer clientId;
@Id
@Column(name = "invoice_id")
private String invoiceId;
@Column(name = "description")
private String description;
@Column(name = "txn_total_amount")
private BigDecimal txnTotalAmount;
@Column(name = "created_time", updatable = false)
@CreationTimestamp
private Date createdTime;
@Column(name = "updated_time")
@UpdateTimestamp
private Date updatedTime;
@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "invoice")
private List<InvoiceLineEntity> invoiceLines;
}
在这种情况下,假设我的一张现有发票有 3 行,我收到一个请求,要求此特定发票已更新,现在它只有 1 行而不是之前的 3 行(因此必须删除其他 2 行),我想用这个 1 InvoiceLineEntity 创建一个新的 Invoice 对象,然后做一个invoiceRepository.save(invoice)
我预计其他 2 个 InvoiceLine 记录将被自动删除,因为该orphanRemoval
标志已启用。
有人可以告诉我如何通过调整上述两个实体的实体关系结构来实现这种关系吗?
解决方案
您的子实体必须是关系的所有者,以便允许删除孤儿
如果您更改并添加mappedBy
到该关系
@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, mappedBy = "bill")
private List<BillLine> billLines;
那么 BillLine 也必须持有一个引用
public class BillLine {
@Id
@Column(name = "line_id")
private String lineId;
@Id
@Column(name = "company_id")
private Integer companyId;
@Id
@Column(name = "bill_id")
private String billId;
@Column(name = "item_id")
private String itemId;
@Column(name = "amount")
private BigDecimal amount;
@ManyToOne
private Bill bill;
}
现在它将删除孤儿
另外,因为您@Id
在每个实体上都有多个。您是否知道必须声明复合类或可嵌入类?如果没有其中一个,则多个 ID 无效。
编辑:
1)我的 bad mappedBy 应该放在里面@OneToMany
而不是@JoinColumn
. 我已经在我的回答中更正了
2)删除@JoinColumn
。你的配置有问题。默认情况下,在保存对主表的引用@OneToMany
的一侧插入一列。@ManyToOne
您可以覆盖这些默认配置并为映射创建一个单独的表,但是您需要@JoinTable
并且我在这里看不到任何原因。
这里
@JoinColumns(value = { @JoinColumn(name = "company_id", referencedColumnName = "company_id"),
@JoinColumn(name = "bill_id", referencedColumnName = "bill_id") })
绝对不属于@OneToMany
以下内容可以应用于@OneToMany
但如前所述,我认为没有任何理由这样做并使不需要单独表的简单映射复杂化。
@JoinTable(joinColumns = @JoinColumn(name = "company_id", referencedColumnName = "company_id"),
inverseJoinColumns = @JoinColumn(name = "bill_id", referencedColumnName = "bill_id") )
在这里查看更多信息Jpa 主键
推荐阅读
- r - 我如何计算 Rstudio 每周不同的破产情况?
- python - 删除在 Pandas 中作为另一行的子字符串找到值的行
- javascript - 建议需要使用javascript代码处理这类问题
- java - 杰克逊 ObjectMapper 在 Spring 的生命周期
- python - 如何在 KivyMD 中编写可重复使用的按钮?
- python - 熊猫更新未反映在 jupyter 笔记本中
- java - 错误 - 解释器不是抽象的,并且不会覆盖抽象方法
- c# - Azure KeyVault:如何创建 clientId 和 clientSecret?
- oop - 这是否被视为程序编程(或贫血模式)?
- java - JPA 在每次迭代后开始消耗越来越多的内存