java - 删除与另一个对象有manyTomany关系的对象

标签 java hibernate jpa entity

我有一个名为 Article 的实体类,以及另一个名为 ArticleTag 的实体。这两个实体是多多关系,这意味着许多文章可以链接到同一个标签,并且许多标签可以与同一篇文章关联。

在我的文章实体中,我有以下内容:

        @ManyToMany(cascade = {CascadeType.ALL})   
        @JoinTable(name = "table_articleId_tagId",
                  joinColumns = {@JoinColumn(name ="article_id")},
                  inverseJoinColumns = {@JoinColumn(name = "tag_id")})
        private Set<ArticleTag> tags = new HashSet<ArticleTag>();

在我的 ArticleTag 实体中,我有以下内容:

    @ManyToMany(mappedBy = "tags")
    private Set<Article> articleSet = new HashSet<Article>();

当我的 Controller 被调用来删除一篇文章时,我在 ArticleDao 类中使用了一个方法,该方法本质上是这样做的:

Transaction tx = session.beginTransaction();
session.delete(article);
tx.commit();

但是,我的文章无法删除。我不确定是什么原因导致此失败。我想知道是否应该先使用 Eager Fetch 删除标签。但这对我来说听起来不对,因为相同的标签可以链接到另一篇文章。那么,删除文章而不删除仍与另一篇文章关联的关联标签的正确方法是什么?

编辑:

感谢@Vlad Mihalcea 的建议。受此启发,我开始考虑通过创建一个名为 ArticleAndTagLink 的中间实体,将 Article 和 ArticleTag 之间的 ManyToMany 关系重构为两个 OneToMany 关系。

所以我的想法是在 Article/ArticleTag 与 ArticleandTagLink 实体之间创建 OneToMany 关系。这将使我能够利用 Article 或 ArticleTag 实体上的“orphanRemoval = true”注释。当我想要删除一篇文章时,此注释将帮助我删除关联的 ArticleandTagLink 对象,并且如果它不再关联任何其他 ArticleTag 对象,我将删除该标签。我认为这可能有效,并且可能比迭代标签更有效。如果有效的话,我明天回来报告!

最佳答案

Hibernate 级联删除与 SQL 删除不同。对于@ManyToMany 关联,删除将传播到实际实体,而不是关联表,这不是您想要的。

要删除这两个表之间的关联,在删除文章之前,您还需要:

  1. 将delete-orphan=true添加到Article.tags

  2. 您需要初始化 Article.tags 集合。

  3. 由于您有双向关联,因此您也必须从标签中删除文章。迭代 Article.tags 并从 Article.tag.articleSet 中删除当前文章(此操作最终可能会导致 N+1 操作,因此 Batch/Subselect获取可能有帮助)。

  4. 从要删除的文章中删除所有标签。

  5. 删除文章

关于java - 删除与另一个对象有manyTomany关系的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24623483/

相关文章:

java - 如何将HashMap存储到值为Array的数据库中?

java - 将 hibernate3 与现有表一起使用

java - 如何从 JPA 中的唯一约束异常中获取字段名称

java - Spring JPA 与 ApplicationContext.xml、DAO 和 Service 为 NULL

java - 如何在 Spring 应用程序中处理生产数据库的架构升级

java - EntityManager的createNativeQuery可以返回结果类即dojo类

java - Dropwizard 将自定义异常反序列化为 JSON?

java - 实时读取 Runtime.getRuntime().exec()

java - 为什么 DialogFragment.dismiss 不立即终止对话框?

java - 无法在 IntStream 上应用 Collectors.groupingBy