【问题标题】:Delete an object that has manyTomany relationship to another object删除与另一个对象有 manyTomany 关系的对象
【发布时间】:2014-08-28 16:42:51
【问题描述】:

我有一个名为 Article 的实体类和另一个名为 ArticleTag 的实体。这两个实体是manyTomany关系,即同一个标签可以关联很多文章,同一个文章可以关联很多标签。

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

        @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>();

当我的控制器被调用来删除一篇文章时,我在我的 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 对象,我将删除该标签。我认为这可能有效,并且可能比遍历标签更有效。如果成功了,我明天再报告!

【问题讨论】:

标签: java hibernate jpa entity


【解决方案1】:

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

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

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

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

  3. 由于您具有双向关联,因此您也必须从标签中删除文章。迭代 Article.tags 并从 Article.tag.articleSet 中删除当前文章(此操作可能以 N+1 操作结束,因此批处理/子选择获取可能会有所帮助)。

  4. 从您要删除的Article 中删除所有标签。

  5. 删除Article

【讨论】:

    猜你喜欢
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2014-08-03
    相关资源
    最近更新 更多