问题
是否可以将行删除到由@ManyToMany注释创建的联接表中?
上下文
使用此架构:
当从public Set<Tag> tags
中删除标签(属于ARTICLE
类的列表)时,也删除了TAGS_ARTICLES
中相应的行,但没有删除TAG
表中的标签。 / p>
唯一的方法是创建一个SQL脚本,或者JPA / Hibernate允许我们使用批注来做到这一点?
代码
我当前的代码是:article.getTags().remove(tag);
此行从列表中删除了标签,但是更改未在数据库中完成。
结论
我看到了这篇文章:How to delete a row in join table with JPA,但也必须删除相对标签(不是我的情况)。
谢谢。
编辑1:数据库中的预期结果
删除前
ARTICLE
| article_id |
| a1 |
| a2 |
| a3 |
TAGS_ARTICLES
| article_id | tag_id |
| a1 | t1 |
| a1 | t2 |
| a2 | t2 |
TAG
| article_id |
| t1 |
| t2 |
从a1标签列表中删除t1
ARTICLE
| article_id |
| a1 |
| a2 |
| a3 |
TAGS_ARTICLES
| article_id | tag_id |
| a2 | t1 |
| a2 | t2 |
TAG
| article_id |
| t1 |
| t2 |
编辑2:加入表格代码
@Entity
public class Article {
...
@ManyToMany
@JoinTable(name = "tags_articles",
joinColumns = @JoinColumn(name = "idarticle"),
inverseJoinColumns = @JoinColumn(name = "idtag")
)
private Set<Tag> tags = new HashSet<>();
...
}
答案 0 :(得分:1)
编辑:查看评论
使用此设置应该会产生想要的结果
class Article {
...
@ManyToMany
@JoinTable(...)
private Set<Tag> tags = new HashSet<>();
}
class Tag {
...
@ManyToMany(mappedBy = "tags")
private Set<Article> articles = new HashSet<>();
}
Article
实体已拥有该关系的所有权。
旧答案。
从
public Set<Tag> tags
删除标签时(ARTICLE中的列表) 类别)到TAGS_ARTICLES的相应行也被删除,但是 而不是将标签放入TAG表。
通过这种方式,我知道孤立的记录不会被删除。您想要删除它们。这是正确的吗?
您可能想尝试使用特定于Hibernate的@Cascade
批注(documentation)。
只需注释您的Collection<T>
字段即可。
@ManyToMany(...)
@Cascade(CascadeType.REMOVE) // or CascadeType.DELETE
private Set<Tag> tags = new HashSet<>();
请确保从org.hibernate.annotations
软件包中添加它。
答案 1 :(得分:1)
实体操作的行为取决于关系的所有权,这取决于将 mappedBy 属性放置在注释中的位置。具有mappedBy
的实体不是所有者。关系的双方不能是所有者。
在这里您需要确定正确的所有者。假设标签是所有者。然后,在删除标签时,关系TAGS_ARTICLES将自动更新。删除TAGS_ARTICLES时,您必须自己删除该关系。
@Entity
public class Tag{
@ManyToMany
Set<Tag_Articles> articles;
//...
}
@Entity
public class Tag_Articles{
@ManyToMany(mappedBy="articles")
Set<Tag> tags;
//...
}
对于上述实体关系,您可以尝试类似以下操作-
entityManager.remove(articles)
for (Tag tag: articles.tags) {
tag.articiles.remove(articles);
}