Hi 打扰大家了...这个问题理论上不应该很难,毕竟官方和各种文档上都有很多的 demo,但自己在实践过程中还是遇到了一个很尴尬的问题:
场景是一篇文章(Article)
有多个标签(Tag)
对 Article
:
public class Article {
...
@ManyToMany(cascade = {CascadeType.ALL})
@JoinTable(name = "article_tag",
joinColumns = @JoinColumn(name = "article_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "tag_id", referencedColumnName = "id"))
private Set<Tag> tagList = new HashSet<>();
}
对 Tag
:
public class Tag {
...
@ManyToMany(mappedBy = "tagList")
private Set<Article> articles=new HashSet<Article>();
}
article 表没有与 tag 有关的字段 tag 表也没有与 article 有关的字段 所有的关系存储在 article_comment 表中:
+------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+-------+
| ID | int(11) | NO | PRI | NULL | |
| article_id | int(11) | YES | | NULL | |
| comment_id | int(11) | YES | | NULL | |
+------------+---------+------+-----+---------+-------+
比如用最简单的语句只是返回一个 Article 对象:
return articleRepository.findBySlug(slug);
在添加 @ManyToMany 字段前是没有问题的,但添加之后就无法查询,会显示以下报错:
Hibernate: select taglist0_.article_id as article_1_2_0_, taglist0_.tag_id as tag_id2_2_0_, tag1_.id as id1_4_1_, tag1_.tag_name as tag_name2_4_1_ from article_tag taglist0_ inner join tag tag1_ on taglist0_.tag_id=tag1_.id where taglist0_.article_id=?
Hibernate: select articles0_.tag_id as tag_id2_2_0_, articles0_.article_id as article_1_2_0_, article1_.id as id1_0_1_, article1_.body as body2_0_1_, article1_.created_at as created_3_0_1_, article1_.description as descript4_0_1_, article1_.favorited as favorite5_0_1_, article1_.favorites_count as favorite6_0_1_, article1_.slug as slug7_0_1_, article1_.title as title8_0_1_, article1_.updated_at as updated_9_0_1_, article1_.user_id as user_id10_0_1_ from article_tag articles0_ inner join article article1_ on articles0_.article_id=article1_.id where articles0_.tag_id=?
Hibernate: select taglist0_.article_id as article_1_2_0_, taglist0_.tag_id as tag_id2_2_0_, tag1_.id as id1_4_1_, tag1_.tag_name as tag_name2_4_1_ from article_tag taglist0_ inner join tag tag1_ on taglist0_.tag_id=tag1_.id where taglist0_.article_id=?
看起来就像是 Article 和 Tag 在互相查询,引用依赖,再之后因为永远在互相查询会引起崩溃,从而:
HHH000100: Fail-safe cleanup (collections) : org.hibernate.engine.loading.internal.CollectionLoadContext@4c5c2744<rs=HikariProxyResultSet@353080062 wrapping Result set representing update count of 3>
Thread starvation or clock leap detected
查询就无法进行下去。
① 对 Article 里的 private Set<Tag> tagList
字段添加 @JsonIgnore 注解,这样返回的结果就不会包含 tag,也就不会报错。
② 修改 getter 方法(之前无论是 lombok 的 @Getter 还是用最经典的 Java getter 方法都不可行),比如重新定义如下:
public Set<Tag> getTagList() {
return new HashSet<Tag>();
}
会返回 "tagList": [],
这个字段,所有都为空。
但这都并不是最终想要的结果 quq
最终目的还是要解决循环依赖,有这样一篇文章: http://springquay.blogspot.com/2016/01/new-approach-to-solve-json-recursive.html 和主题类似,但里面的方法似乎都仍然没有效果。
所以目前就卡在这个地方,完全没有思路,在网上基本找到所有类似的问题都没有相应解决方法...汗...想请问下 V 站的大家有没有遇到过类似的问题或者有什么调试的思路可以分享下么~谢谢啦。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.