我已经玩了几天玩游戏框架,但遇到了一个我无法解决的问题:假设你有一些“用户”和“文件”类。两者互相引用,并使用ebean(@ManyToOne,@ OneToMany)保存在数据库中。现在当用户返回JSON时,我得到一个stackoverflow错误。这是一个游戏中的错误还是我错过了什么?
@Entity
public class File extends Model {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
public Long id;
@ManyToOne(cascade=CascadeType.ALL)
public User author;
}
@Entity
public class User extends Model {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
public Long id;
@OneToMany(mappedBy="author", cascade=CascadeType.ALL)
public List<File> files;
}
import play.libs.Json;
public class Users extends Controller {
public static Result getJSON() {
List<User> users = new Model.Finder<String, User>(String.class, User.class).all();
return ok(Json.toJson(users));
}
}
堆栈跟踪:
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain:
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
models.User["files"]->com.avaje.ebean.common.BeanList[0]->models.File["author"]->
.
.
.
->models.User["files"])
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:164) ~[jackson-mapper-asl.jar:1.9.10]
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) ~[jackson-mapper-asl.jar:1.9.10]
at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) ~[jackson-mapper-asl.jar:1.9.10]
at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) ~[jackson-mapper-asl.jar:1.9.10]
at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) ~[jackson-mapper-asl.jar:1.9.10]
at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:72) ~[jackson-mapper-asl.jar:1.9.10]
java.lang.StackOverflowError: null
at java.lang.ClassLoader.defineClass1(Native Method) ~[na:1.7.0_45]
at java.lang.ClassLoader.defineClass(ClassLoader.java:800) ~[na:1.7.0_45]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) ~[na:1.7.0_45]
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) ~[na:1.7.0_45]
at java.net.URLClassLoader.access$100(URLClassLoader.java:71) ~[na:1.7.0_45]
at java.net.URLClassLoader$1.run(URLClassLoader.java:361) ~[na:1.7.0_45]
答案 0 :(得分:6)
好的,经过数小时的谷歌搜索我找到了解决方案: 有一个注释@JsonIgnore(从org.codehaus.jackson.annotate.JsonIgnore导入它),它告诉JSON方法忽略这个属性。
编辑:进一步深入研究,在JSON序列化期间处理循环引用的更清洁的解决方案是编写自定义的De-和Serializer。史蒂夫希尔的一篇非常好的文章可以在这里找到:http://dev.sghill.net/2012/04/how-do-i-write-jackson-json-serializer.html