hibernate - JPA:如何删除单向多对多关系中的链接记录?

标签 hibernate jpa

我有实体“事件”和“发票”的单向多对多映射。映射仅在事件实体中设置(我不需要从发票端访问事件)。

@ManyToMany
@JoinTable(name = "OP_ACTIVITY_INVOICE_XREF", joinColumns = @JoinColumn(name = "ACTIVITY_ID", referencedColumnName = "OBJECT_ID"), inverseJoinColumns = @JoinColumn(name = "INVOICE_ID", referencedColumnName = "OBJECT_ID"))
private Set<Invoice> invoices;

插入和更新工作正常,但我在删除事件时遇到问题。删除事件代码如下:

    activity.getInvoices().clear();
    em.remove(activity);

当我运行这些代码时,我认为他们会首先从连接表中删除记录,然后删除事件记录(发票记录应保持不变)。但连接表中的记录永远不会被删除。我收到此外键错误:

[STDOUT] Hibernate: delete from OP_ACTIVITY where OBJECT_ID=?
[JDBCExceptionReporter] SQL Error: 1451, SQLState: 23000 
ERROR [JDBCExceptionReporter] Cannot delete or update a parent row: a foreign key constraint fails (`prod/op_activity_invoice_xref`.......

我在这里做错了什么?请帮忙,谢谢。

最佳答案

我认为您需要@ManyToMany(cascade = {CascadeType.REMOVE})选项。

CascadeType.REMOVE: When deleting an entity, also delete the entities held in this field.

事件中:

@ManyToMany(cascade = {CascadeType.REMOVE})
@JoinTable(name = "OP_ACTIVITY_INVOICE_XREF", joinColumns = @JoinColumn(name = "ACTIVITY_ID",  referencedColumnName = "OBJECT_ID"), inverseJoinColumns = @JoinColumn(name = "INVOICE_ID", referencedColumnName = "OBJECT_ID"))
private Set<Invoice> invoices;

显然 REMOVE 不应该与 @ManyToMany (来自 JPA 2.0 规范)一起使用:

The relationship modeling annotation constrains the use of the cascade=REMOVE specification. The cascade=REMOVE specification should only be applied to associations that are specified as OneToOne or OneToMany. Applications that apply cascade=REMOVE to other associations are not portable.

您可以在 Hibernate 中尝试供应商扩展@OnDelete:

@OnDelete(action=OnDeleteAction.CASCADE)

或者您可以手动执行:

for (Invoice invoice : activity.getInvoices()) {
   em.remove(invoice);
}
activity.getInvoices().clear();
em.remove(activity);
... flush() etc...

或者你可以注释@PreRemove: 将以下方法添加到不是关系所有者的实体(Invoice)

@PreRemove
private void removeInvoicesFromActivities() {
    for (Activity a : activities) {
        a.getInvoices().remove(this);
    }
}

关于hibernate - JPA:如何删除单向多对多关系中的链接记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20627270/

相关文章:

java - 运行单元测试时出现 MismatchedTokenException

java - Hibernate ReturningWork<Long> 接口(interface)的用途是什么?

java - 使用列值 hibernate 和排序

mysql - org.hibernate.HibernateException : Missing column: auth_password in Spring Boot application

jpa - 如何模拟@PrePersist 方法?

java.time.LocalDateTime 在带有 hibernate 的 JPA 中被持久化为tinyblob而不是 TemporalType

java - Spring Security 多个登录用户失败

没有带注解的 spring hibernate

java - Hibernate JPA 简化了 update()、delete()、add() 的代码

java - 事务可以跨越多个具有无状态+事务范围的持久性上下文的业务方法吗