Hibernate - 自动更新@ManyToMany
Hibernate - automatic @ManyToMany update
我有 Article
个实体,它有相关的 Tag
s:
@Entity
@Table(name = "articles")
public class Article implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Tag> tags;
}
和 Tag
实体,它具有相关的 Article
s:
@Entity
@Table(name = "tags")
public class Tag implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Article> articles;
}
是否有机会以某种方式配置 Annotations
,如果我用指定的 Tag
:
保存 Article
//simplified code
Tag tag = new Tag();
tags.add(tag)
article.setTags(tags);
articleService.save(article);
Article
与Tag
相关的会自动更新,无需明确调用add
方法(tag.getArticles().add(article)
)?或者我必须手动完成?
这是单元测试的一部分,展示了我试图实现的目标:
service.save(new TagDTO(null, tagValue, emptyArticles));
TagDTO tag = service.getAll().get(0);
List<TagDTO> tags = new ArrayList<>();
tags.add(tag);
articleService.save(new ArticleDTO(null, tags, articleContent));
List<ArticleDTO> articles = articleService.getAll();
assertEquals(1, articles.size());
final ArticleDTO articleWithTags = articles.get(0);
assertEquals(1, articleWithTags.getTags().size());
tags = service.getAll();
assertEquals(1, tags.size());
final TagDTO tagWithArticle = tags.get(0);
final List<ArticleDTO> articlesWithTag = tagWithArticle.getArticles();
assertEquals(1, articlesWithTag.size()); //it fails
现在失败了,因为 Tag
没有更新相关的 Article
。
提前感谢您的回答!
您的多对多关系缺少 mappedBy
属性。如果你不使用它,那么 hibernate 会认为你有两个不同的单向关系。
我的意思是你的代码代表这个:
Article * ------------------[tags]-> * Tag
Tag * ------------------[articles]-> * Article
而不是这个:
Article * <-[articles]------[tags]-> * Tag
这是在 Article
和 Tag
之间建立一个多对多双向关系的一种方法。注意 Tag->articles 集合的 mappedBy
属性。
@Entity
@Table(name = "articles")
public class Article implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Tag> tags;
}
@Entity
@Table(name = "tags")
public class Tag implements Serializable{
//other things
@ManyToMany(mappedBy="tags" ,cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Article> articles;
}
编辑:看看这个 Hibernate Documentation 了解如何编写不同的双向关联场景。
我有 Article
个实体,它有相关的 Tag
s:
@Entity
@Table(name = "articles")
public class Article implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Tag> tags;
}
和 Tag
实体,它具有相关的 Article
s:
@Entity
@Table(name = "tags")
public class Tag implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Article> articles;
}
是否有机会以某种方式配置 Annotations
,如果我用指定的 Tag
:
Article
//simplified code
Tag tag = new Tag();
tags.add(tag)
article.setTags(tags);
articleService.save(article);
Article
与Tag
相关的会自动更新,无需明确调用add
方法(tag.getArticles().add(article)
)?或者我必须手动完成?
这是单元测试的一部分,展示了我试图实现的目标:
service.save(new TagDTO(null, tagValue, emptyArticles));
TagDTO tag = service.getAll().get(0);
List<TagDTO> tags = new ArrayList<>();
tags.add(tag);
articleService.save(new ArticleDTO(null, tags, articleContent));
List<ArticleDTO> articles = articleService.getAll();
assertEquals(1, articles.size());
final ArticleDTO articleWithTags = articles.get(0);
assertEquals(1, articleWithTags.getTags().size());
tags = service.getAll();
assertEquals(1, tags.size());
final TagDTO tagWithArticle = tags.get(0);
final List<ArticleDTO> articlesWithTag = tagWithArticle.getArticles();
assertEquals(1, articlesWithTag.size()); //it fails
现在失败了,因为 Tag
没有更新相关的 Article
。
提前感谢您的回答!
您的多对多关系缺少 mappedBy
属性。如果你不使用它,那么 hibernate 会认为你有两个不同的单向关系。
我的意思是你的代码代表这个:
Article * ------------------[tags]-> * Tag
Tag * ------------------[articles]-> * Article
而不是这个:
Article * <-[articles]------[tags]-> * Tag
这是在 Article
和 Tag
之间建立一个多对多双向关系的一种方法。注意 Tag->articles 集合的 mappedBy
属性。
@Entity
@Table(name = "articles")
public class Article implements Serializable{
//other things
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Tag> tags;
}
@Entity
@Table(name = "tags")
public class Tag implements Serializable{
//other things
@ManyToMany(mappedBy="tags" ,cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private List<Article> articles;
}
编辑:看看这个 Hibernate Documentation 了解如何编写不同的双向关联场景。