我正在研究一个eclipselink项目,其中一个用户可以像在社交媒体网站上完成另一个用户"关注"。我使用User
实体(引用一个名为users
的表(设置此设置,该表有"关注者"(关注该用户的用户(的列表和另一个"关注"列表(用户正在关注的用户(。该关系定义在一个称为followers
的单独表中,该表包含以下用户ID(user_id
(和以下用户ID(follower_id
(的列。
我的用户模型看起来像这样:
@Entity
@Table(name = "users")
@NamedQuery(name = "User.findAll", query = "SELECT u FROM USER u")
public class User {
// other attributes
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "follower", joinColumns = @JoinColumn(
name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(
name = "follower_id", referencedColumnName = "id"))
private List<User> followers;
@ManyToMany(mappedBy = "followers")
private List<User> following;
// other getters and setters
public List<User> getFollowers() {
return this.followers;
}
public List<User> getFollowing() {
return this.following;
}
}
getFollowers()
方法似乎可以正常工作,但是当getFollowing()
称为我会得到一堆控制台垃圾邮件,该垃圾邮件最终在stackoverflowExcept中:
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion
(StackOverflowError) (through reference chain:
org.eclipse.persistence.indirection.IndirectList[0]-
>org.myproject.model.User["followers"]-
>org.eclipse.persistence.indirection.IndirectList[0]-
>org.myproject.model.User["following"]-
...
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase
.serializeFields(BeanSerializerBase.java:518)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize
(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer
.serializeContents(IndexedListSerializer.java:94)
at com.fasterxml.jackson.databind.ser.impl.IndexedListSerializer
.serializeContents(IndexedListSerializer.java:21)
...
请让我知道我是否应该提供更多堆栈跟踪。有提示吗?
每次您拥有@OneToMany
(集合(时,您需要向其添加@JsonIgnore
,否则会导致无限循环,从而导致堆栈溢出异常,因为它会一直在父母之间查找(一侧(和孩子(许多侧(有关解决此类问题的更多信息,请查看此出色的文章http://www.baeldung.com/jackson-bidirectional-relationships-and-and-infinite-recursion
public class A {
private String name;
@JsonIgnoreProperties(value = "linkToA") // remove field to avoid loop
private B linkToB;
}
public class B {
private String name;
@JsonIgnoreProperties(value = "linkToB") // remove field to avoid loop
private A linkToA;
}
我尝试了我在网络中发现的所有内容,但它不起作用。没有任何注释。但是我在与这个问题进行了巨大的战斗后找到了解决方案。
第一点您需要添加到两个实体(而不是关系一个实体(:
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "relationClass"})
public class YourClass { ...
}
其中"关系类"是您类关系的列表/集合的名称:
例如:
@OneToMany(mappedBy = "yourClass", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
private Set<RelationClass> relationClass;
您还需要指定注释中的" HibernatelazyInitializer","处理程序",或者会导致序列化问题。
之后,如果您看到定义关系表的表,并且您会在其中看到行,并且在您的JSON响应中将不再有任何循环。因此,我认为最好的解决方案也是为关系表创建一个存储库,并从那里访问数据。
希望它能帮助某人!
我认为先前答案中的问题是注释的包。在文章中@jsonmanagedReference和@jsonbackReference效果很好。
但是包应该是com.fasterxml.jackson.annotation。
有时可能会导入其他软件包,并且无法解决问题。
另外添加
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
模型的类定义效果很好。
您也可以使用如下态公共类用户{}