我有像这样的双向关系......
Person.java
public class Person{
@JsonIgnore
@OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL,
fetch=FetchType.EAGER, mappedBy="person")
private Set<PeopleOrg> organization;
.....
}
PersonOrganization.java
public class PersonOrganization{
@JsonIgnore
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="PERSONID", nullable=false)
private Person person;
}
即使使用@JsonIgnore
注释,我在尝试检索Person记录时也会收到无限递归错误。我在1.6版本中尝试过新的注释。 @JsonBackReference
和@JsonManagedReference
。即使这样,我也会得到无限的递归..
@JsonBackReference("person-organization")
上的Person
和@JsonManagedReference("person-organization")
上的PersonOrganization
org.codehaus.jackson.map.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.entity.Person["organization"]->org.hibernate.collection.PersistentSet[0]->com.entity.PersonOrganization["person"]->com.entity.Person["organization"]->org.hibernate.collection.PersistentSet[0]...
即使我交换了注释,我仍然会遇到此异常..如果映射或我使用JSON注释的方式有问题,请告诉我。感谢
答案 0 :(得分:40)
我之前遇到过这种情况。但是在将@JsonIgnore从私有字段移动到字段的getter 之后,无限递归就消失了。所以我的猜测是,@ JsonIgnore可能无法在私人领域工作。但是,javadoc或Jackson Java JSON处理器的教程没有提到这一点,所以我不能100%肯定。仅供参考。
答案 1 :(得分:10)
以下链接说明您应该注释JSON工具用于遍历对象图的方法,以指示它忽略遍历。
http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/annotate/JsonIgnore.html
在我的情况下,我有两个相关的对象,如产品&lt; - &gt; ProductImage。所以JSON解析器进入一个无限循环,在下面输出@JsonIgnore注释来获取方法
@JsonIgnore
public Product getImageOfProduct() {
return imageOfProduct;
}
在ProductImage和
中@JsonIgnore
public Set<ProductImage> getProductImages() {
return productImages;
}
在产品中。
通过注释,事情正常。
答案 2 :(得分:5)
我知道这个问题并不是专门针对Spring Data REST的,但我在Spring Data REST的上下文中遇到了这个异常,并希望分享问题所在。我有一个涉及没有存储库的实体的双向关系。创建存储库使循环消失。
答案 3 :(得分:2)
显然,自Jackson 1.6以来,您可以使用@JsonManagedReference和@JsonBackReference来有效解决无限递归问题。
我不打算详细介绍,但是将这些类改为以下格式可以解决问题。
public class Person{
@OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="person")
@Column(nullable = true)
@JsonManagedReference
private Set<PeopleOrg> organization;
.....
}
public class PersonOrganization{
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name="PERSONID")
@JsonBackReference
private Person person;
}
基本上,杰克逊使用编组过程将Set<PeopleOrg> organization
(参考a的前向部分)转换为类似json的格式,然后查找引用的后半部分Person person
并且不将其序列化
致谢 - Kurt Bourbaki&amp;更多信息 - http://keenformatics.blogspot.co.ke/2013/08/how-to-solve-json-infinite-recursion.html
答案 4 :(得分:1)
如果A有B&amp; B有A.
这是一对一关系,但形成循环关系。
在任何一个类中,使用JustIgnore注释。
class A
{
B b;
}
class B
{
@JsonIgnore
A a;
}
这也适用于其中一对多的关系。
答案 5 :(得分:0)
这可能有点旧,但你可以在类级添加@JsonIgnore,它应该忽略所有属性。 e.g
@JsonIgnore("productImaes","...")
public class Product{ ...
}
答案 6 :(得分:0)
有时成员字段可能内部引用自身的同一类类型,这可能会导致toJson
时出现无限递归。
例如:您有一个成员字段Klass a
,而该Klass的类定义如下所示。
class Klass {
Klass mySibling;
public toString() {
return "something" + mySibling.whateverMethod;
}
}
解决方案:重构成员字段,消除内部引用。
答案 7 :(得分:0)
此异常是因为,您的构造函数字段不正确,请在您的类中再次检查构造函数属性,并检查映射是否正确,
保留两个构造函数,首先是零构造,第二个构造函数是字段,两者都应该包含超级
答案 8 :(得分:0)
对我来说,我尝试了@ JsonIgnore,@ JsonManagedReference / @ JsonBackReference,但没有任何效果,直到我阅读了此Exception thrown ["hibernateLazyInitializer"] solution 1和此Exception thrown ["hibernateLazyInitializer"] solution 2
解决方案1将从fetch.LAZY更改为fetch.EAGER,解决方案2使用@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
,当然在两个解决方案中都使用@JsonIgnore
答案 9 :(得分:-2)
杰克逊通过打电话给吸气者来研究反思。我也遇到过这样一种情况:我在类中有一个相同Object的getter。杰克逊通过反复称自己的吸气剂进入无限递归吃掉筹码。删除了吸气剂,然后它被修复了。
我的建议: 如果你想使用jackson转换一个对象,就不要保留引用相同对象的getter,就像单例一样。