【问题标题】:Is there a way to let Hibernate handle removal of an entry in a @ManyToMany association if I remove an entity not managing this association?如果我删除不管理此关联的实体,是否有办法让 Hibernate 处理删除 @ManyToMany 关联中的条目?
【发布时间】:2019-05-07 16:20:44
【问题描述】:

如果我删除了不管理此关联的实体,是否有办法让 Hibernate 处理删除 @ManyToMany 关联的 JoinTable 中的条目?

据我了解,如果我有这样的 @ManyToMany 关联:

@Entity
public class AlertConfigurationVersion {

    @JoinTable(
                name = SUBJECT_ALERTCONFIGURATION_VERSION_TABLE,
                joinColumns = @JoinColumn(name = "alert_configuration_version_id"),
                inverseJoinColumns = @JoinColumn(name = "subject_id")
    @ManyToMany(cascade = {
                CascadeType.DETACH,
                CascadeType.MERGE,
                CascadeType.REFRESH,
                CascadeType.PERSIST})
    private Set<Subject> subjects = new HashSet<>();
}

然后,如果我删除 AlertConfigurationVersion,@ManyToMany 表将针对任何指向它的 Subjects 正确更新。

但就我而言,我正在删除 Subject(使用标准存储库方法),现在我得到一个带有底层的讨厌的 org.hibernate.exception.ConstraintViolationException

org.postgresql.util.PSQLException: ERROR: update or delete on table "subject" violates foreign key constraint "fks123x93urj80014yg4vem4h43" on table "subject_alertconfigurationversion"
  Detail: Key (id)=(9b915613-f37d-45c2-8fd8-8da4f9291aea) is still referenced from table "subject_alertconfigurationversion".

我可以让 Hibernate 以某种方式处理这种情况吗?理想情况下,不要通过使这种关联双向,因为没有业务逻辑需要。不过,我认为这并不重要。

我正在使用 Lombok 生成哈希码和 equals,但我也尝试根据 https://dev.to/alagrede/why-i-dont-want-use-jpa-anymore-flhttps://developer.jboss.org/wiki/EqualsAndHashCode?_sscc=t 的建议从这些中排除引用和/或 id

相关:ManyToMany with cascade all only cascading one way,虽然这是 5 年前的事,并没有引起太多关注,但现在甚至那时可能会有一些方式。

另一个相关问题:Hibernate many-to-many cascading delete,我通过复制可连接件尝试了最佳答案中的“hack”,但这会导致所有其他类型的问题,Vlad Mihalcae 明确表示(在其他地方)不要这样做。

https://hibernate.atlassian.net/browse/HHH-12239 上还有一个关于 Hibernate 的未解决问题,看起来像我的问题,所以它似乎被认为是一个错误,但我不能 100% 确定它是否适用于我的情况。问题在于双向关联。

【问题讨论】:

    标签: java spring hibernate jpa spring-data-jpa


    【解决方案1】:

    Subject 实体不知道此关联时,Hibernate 如何从SUBJECT_ALERTCONFIGURATION_VERSION_TABLE 中删除关联的行?

    解决此问题的唯一方法是使用基于 FK 的 CASCADE ON DELETE:

    ALTER TABLE SUBJECT_ALERTCONFIGURATION_VERSION_TABLE
    ADD CONSTRAINT fk_alert_configuration_version_subject_id
    FOREIGN KEY (subject_id) REFERENCES subject 
    ON DELETE CASCADE
    

    【讨论】:

    • 有没有不需要直接在数据库上创建FK的方法?在向主题实体提供此关联的知识时,它将如何工作?
    • Vlad 我认为 Hibernate 会为应用程序的整个域模型构建一个内存模型,因此它会意识到当在多对多关联中有一个实体引用要删除的实体时,它删除该实体时还需要更新该连接表。
    • 我对将其设为双向关联的想法持开放态度,如果这样可以让任何事情变得更容易,但我试过了,但它对我当时使用的代码没有任何影响。跨度>
    • 由于HHH-12239,最好在数据库表级别解决这个问题。为什么你不想采用这种方法?
    • 对不起,我完全错过了你的评论。在数据库级别执行此操作可能是一种选择,我将讨论它。不过,我们更愿意让 Hibernate 管理整个数据库。我在vladmihalcea.com/… 阅读了您的博客,我想我们也可以通过在连接表实体中添加一个@OnDelete(action = OnDeleteAction.CASCADE) 来实现相同的目的,但这似乎有点矫枉过正。
    猜你喜欢
    • 1970-01-01
    • 2015-04-05
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 2017-11-17
    • 1970-01-01
    相关资源
    最近更新 更多