简体   繁体   English

仅将行删除到联接表中

[英]Delete a row only into the join table

Question

Is it possible to delete a row into a join table created by @ManyToMany annotation? 是否可以将行删除到由@ManyToMany注释创建的联接表中?

Context 语境

With this schema : 使用此架构:

  • TAG 标签
  • TAGS_ARTICLES TAGS_ARTICLES
  • ARTICLE 文章

When a tag is removed from public Set<Tag> tags (a list into ARTICLE class) corresponding rows into TAGS_ARTICLES is removed too, but not the tag into TAG table. 当标签从去除public Set<Tag> tags (名单成ARTICLE类)相应行到TAGS_ARTICLES也会被删除,但不是标记为TAG表。

The only way is to create a SQL script or JPA/Hibernate allow us to do that with annotations? 唯一的方法是创建一个SQL脚本,或者JPA / Hibernate允许我们使用批注来做到这一点?

Code

My current code is : article.getTags().remove(tag); 我当前的代码是: article.getTags().remove(tag);

This line remove the tag from the list, but the change is not done in database. 该行从列表中删除了标记,但是更改未在数据库中完成。

Conclusion 结论

I saw this post : How to delete a row in join table with JPA , but relative tag must be deleted too (not my case). 我看到了这篇文章: 如何使用JPA删除联接表中的行 ,但也必须删除相对标记(不是我的情况)。

Thanks. 谢谢。

Edit 1 : Expected result in database 编辑1:数据库中的预期结果

Before delete 删除前

ARTICLE

| article_id |
| a1         |
| a2         |
| a3         |

TAGS_ARTICLES

| article_id | tag_id |
| a1         | t1     |
| a1         | t2     |
| a2         | t2     |

TAG

| article_id |
| t1         |
| t2         |

After delete t1 from a1 tag list 从a1标签列表中删除t1之后

ARTICLE

| article_id |
| a1         |
| a2         |
| a3         |

TAGS_ARTICLES

| article_id | tag_id |
| a2         | t1     |
| a2         | t2     |

TAG

| article_id |
| t1         |
| t2         |

Edit 2 : Join table code 编辑2:联接表代码

@Entity
public class Article {
     ...
     @ManyToMany
     @JoinTable(name = "tags_articles",
        joinColumns = @JoinColumn(name = "idarticle"),
        inverseJoinColumns = @JoinColumn(name = "idtag")
     )
     private Set<Tag> tags = new HashSet<>();
     ...
}

Edit: see comments 编辑:查看评论

Using this set-up should produce the wanted result 使用此设置应产生想要的结果

class Article {
   ...  

   @ManyToMany
   @JoinTable(...)
   private Set<Tag> tags = new HashSet<>();
}

class Tag {
   ...

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

The Article entity is taking ownership of the relationship. Article实体已拥有该关系的所有权。


Old answer . 旧答案

When a tag is removed from public Set<Tag> tags (a list into ARTICLE class) the corresponding row into TAGS_ARTICLES is removed too, but not the tag into TAG table. public Set<Tag> tags (ARTICLE类中的列表)中删除标记时,TAGS_ARTICLES中的相应行也将被删除,但标记中的表不会被删除。

By this I understand that the orphaned records are not deleted. 通过这种方式,我知道孤立的记录不会被删除。 And you want to delete them. 您想要删除它们。 Is this correct? 这个对吗?

You might want to try using the Hibernate specific @Cascade annotation ( documentation ). 您可能想尝试使用特定于Hibernate的@Cascade批注( 文档 )。
Just annotate your Collection<T> field. 只需注释您的Collection<T>字段。

@ManyToMany(...)
@Cascade(CascadeType.REMOVE) // or CascadeType.DELETE
private Set<Tag> tags = new HashSet<>();

Be sure to include it from the org.hibernate.annotations package. 确保从org.hibernate.annotations包中包括它。

The behavior of entity operation is depends on ownership of the relation, which is determined by where you place the mappedBy attribute to the annotation. 实体操作的行为取决于关系的所有权,关系的所有权取决于您将mapedBy属性放置到注释的位置。 Entity having mappedBy is the one which is not the owner. 具有mappedBy实体不是所有者。 Both side of relationship cannot be owner. 关系的双方不能是所有者。

Here you need to decide the correct owner. 在这里,您需要确定正确的所有者。 Let say the Tag is the owner. 假设标签是所有者。 Then when deleting a Tag the relation TAGS_ARTICLES will be updated automatically. 然后,在删除标签时,关系TAGS_ARTICLES将自动更新。 when deleting a TAGS_ARTICLES you have to take care of deleting the relation yourself. 删除TAGS_ARTICLES时,您必须自己删除该关系。

@Entity
public class Tag{
    @ManyToMany
    Set<Tag_Articles> articles;
    //...
}

@Entity
public class Tag_Articles{
    @ManyToMany(mappedBy="articles")
    Set<Tag> tags;
    //...
}

For the entity relationship like above, you can try something like this - 对于上述的实体关系,您可以尝试执行以下操作-

entityManager.remove(articles)
for (Tag tag: articles.tags) {
     tag.articiles.remove(articles);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM