【发布时间】:2018-12-17 00:32:08
【问题描述】:
我将 TomEE 9.0.12 与 Hibernate 5.3.7 一起使用,由于 json 递归性,我目前遇到了 stackoverflow 异常。请注意,我没有使用 jackson,理想情况下也不想使用,而是使用 TomEE+ 附带的标准:org.apache.johnzon。
例外情况:
Caused by: java.lang.StackOverflowError
at org.apache.johnzon.mapper.Mappings.findOrCreateClassMapping(Mappings.java:340)
at org.apache.johnzon.mapper.MappingGeneratorImpl.doWriteObjectBody(MappingGeneratorImpl.java:240)
这是我的 User.java 类:
import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
/**
* A user
*/
@Entity
@Table(name = "users")
public class User implements Serializable {
private static final long serialVersionUID = -9012412584251217L;
// TODO: 16/12/2018 they keep nesting each other: { user { posts { user { posts } } } }
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "username")
private String username;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "salt")
private String salt;
@OneToMany(mappedBy = "user")
private Set<Post> posts = new HashSet<>();
/**
* Constructs an empty user (for persistence purposes)
*/
public User() {}
// Setters and getters removed for convenience
}
这是我的 Post.java
import javax.persistence.*;
import java.io.Serializable;
/**
* Project created by ExpDev
*/
@Entity
@Table(name = "posts")
public class Post implements Serializable {
private static final long serialVersionUID = -9887234238952234L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
@Column(name = "data")
private String data;
/**
* Constructs an empty post (for persistence purposes)
*/
public Post() {}
// Setters and getters removed for convenience
}
问题
问题是他们会不断地互相引用。用户会引用帖子,而用户又会引用用户,而用户又会引用帖子——于是邪恶的循环继续下去。
我知道我可以在 User.java 中的“用户”上使用 org.apache.johnzon 的注释 @JsonbTransient 使其不序列化它,但这使得它永远不会显示(我想要,但有条件)。我为什么要这样?
因为,假设 GET /users/1 被访问,1 是用户的 id,我想显示所有用户的帖子(或至少是他们的 ID),但不希望它返回给用户(用户内的帖子内的嵌套用户)。
但是,如果 GET /api/posts/3, 3 是 id,我希望它显示发布帖子的用户,而不是用户内部的帖子。
所以基本上,注释必须在某种程度上是有条件的,并且是具体的。目前,这就是我检索和显示用户的方式(访问该方法时,框架会自动将返回的对象转换为 JSON)。
@GET
@Path("/{id}")
public User get(@PathParam("id") Long id) {
// Find the user and return them
return HiberUtil.getSession().get(User.class, id);
}
提前感谢您!我已经搜索了 5 个小时,但没有解决方案或阅读材料能够解决我的问题。
【问题讨论】:
标签: java json hibernate stack-overflow apache-tomee