Spring 启动 JPA:递归 JSON-自连接关系中的视图
Spring boot JPA: recursion on JSON-view in a self join relationShip
对于我正在尝试构建的项目,我需要从用户 Class 到 Class 用户的多对多关系。(用户有朋友,朋友是用户的朋友)。
尝试使用 JPA 从 SpringBoot 中获取 Json 时。我在我的 JSON 上得到一个递归循环。(只有当两个用户是彼此的朋友时才会发生这种情况)
我知道会发生什么,但找不到问题的解决方案。
如您所见,我对 'filter' 视图使用了不同的视图。问题是:如何停止递归?
@Entity
public class User {
@Id
@GeneratedValue
@JsonView(JsonViews.UserView.class)
private long userId;
@JsonView(JsonViews.UserView.class)
private String username;
@JsonView(JsonViews.UserView.class)
private String password;
@JsonView(JsonViews.UserView.class)
private String email;
@JsonView(JsonViews.UserView.class)
private String location;
//private String avatar;
@JsonView(JsonViews.UserView.class)
private int ranking;
private String UserStatus;
//Friend Relation Many > Many
@JsonView({JsonViews.UserView.class, JsonViews.FriendWith.class})
@ManyToMany()
private List<User> friendsWith;
@ManyToMany(mappedBy = "friendsWith")
private List<User> friendOf;
@JsonView({JsonViews.UserView.class, JsonViews.Player.class})
@OneToMany(mappedBy = "user")
private List<Player> player;
public User() {
this.friendsWith = new ArrayList<>();
this.friendOf = new ArrayList<>();
}
public User(String username, String password, String email, String location, int ranking) {
this();
//this.userId = userId;
this.username = username;
this.password = password;
this.email = email;
this.location = location;
this.ranking = ranking;
}
// and th usual getters and setters
堆栈:
2019-12-10 22:17:52.414 ERROR 1618 --- [nio-8084-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service()
for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (WhosebugError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
ETC.... ETC.....
为了完整性 Json 浏览量 class:
public class JsonViews {
public class UserView { };
public class AComplete extends UserView { };
public class BComplete extends UserView { };
public class FriendsWith extends UserView {};
public class FriendsOf extends UserView {};
public class Player extends UserView {};
}
尝试使用 @JsonIdentityInfo
注释,在这里你可以告诉 Jackson POJO id 是什么,所以它不会重复:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId")
public class User {
public long userId;
public String name;
public List<User> friends;
}
这将生成以下 JSON:
{
"userId" : 11,
"name" : "A",
"friends" : [ {
"userId" : 22,
"name" : "B",
"friends" : [ 11, {
"userId" : 33,
"name" : "C",
"friends" : [ ]
} ]
} ]
}
请注意,在内部用户 B 中,如果用户已被添加到 JSON 正文 [ 11, {
。
,则好友列表仅包含 ID
对于我正在尝试构建的项目,我需要从用户 Class 到 Class 用户的多对多关系。(用户有朋友,朋友是用户的朋友)。 尝试使用 JPA 从 SpringBoot 中获取 Json 时。我在我的 JSON 上得到一个递归循环。(只有当两个用户是彼此的朋友时才会发生这种情况)
我知道会发生什么,但找不到问题的解决方案。 如您所见,我对 'filter' 视图使用了不同的视图。问题是:如何停止递归?
@Entity
public class User {
@Id
@GeneratedValue
@JsonView(JsonViews.UserView.class)
private long userId;
@JsonView(JsonViews.UserView.class)
private String username;
@JsonView(JsonViews.UserView.class)
private String password;
@JsonView(JsonViews.UserView.class)
private String email;
@JsonView(JsonViews.UserView.class)
private String location;
//private String avatar;
@JsonView(JsonViews.UserView.class)
private int ranking;
private String UserStatus;
//Friend Relation Many > Many
@JsonView({JsonViews.UserView.class, JsonViews.FriendWith.class})
@ManyToMany()
private List<User> friendsWith;
@ManyToMany(mappedBy = "friendsWith")
private List<User> friendOf;
@JsonView({JsonViews.UserView.class, JsonViews.Player.class})
@OneToMany(mappedBy = "user")
private List<Player> player;
public User() {
this.friendsWith = new ArrayList<>();
this.friendOf = new ArrayList<>();
}
public User(String username, String password, String email, String location, int ranking) {
this();
//this.userId = userId;
this.username = username;
this.password = password;
this.email = email;
this.location = location;
this.ranking = ranking;
}
// and th usual getters and setters
堆栈:
2019-12-10 22:17:52.414 ERROR 1618 --- [nio-8084-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service()
for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (WhosebugError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
org.hibernate.collection.internal.PersistentBag[0]->
nl.hva.ewa.stratego.backend.models.User["friendsWith"]->
ETC.... ETC.....
为了完整性 Json 浏览量 class:
public class JsonViews {
public class UserView { };
public class AComplete extends UserView { };
public class BComplete extends UserView { };
public class FriendsWith extends UserView {};
public class FriendsOf extends UserView {};
public class Player extends UserView {};
}
尝试使用 @JsonIdentityInfo
注释,在这里你可以告诉 Jackson POJO id 是什么,所以它不会重复:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId")
public class User {
public long userId;
public String name;
public List<User> friends;
}
这将生成以下 JSON:
{
"userId" : 11,
"name" : "A",
"friends" : [ {
"userId" : 22,
"name" : "B",
"friends" : [ 11, {
"userId" : 33,
"name" : "C",
"friends" : [ ]
} ]
} ]
}
请注意,在内部用户 B 中,如果用户已被添加到 JSON 正文 [ 11, {
。