SpringMVC-JSON无限递归
我有这样的双向关系 Person.javaSpringMVC-JSON无限递归,json,spring-mvc,Json,Spring Mvc,我有这样的双向关系 Person.java public class Person{ @JsonIgnore @OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL, fetch=FetchType.EAGER, mappedBy="person") private Set<PeopleOrg> organization; ..... }
public class Person{
@JsonIgnore
@OneToMany(targetEntity=PersonOrganization.class, cascade=CascadeType.ALL,
fetch=FetchType.EAGER, mappedBy="person")
private Set<PeopleOrg> organization;
.....
}
即使使用@JsonIgnore
注释,我在尝试检索个人记录时也会遇到无限递归错误。我尝试了1.6版本中的新注释@JsonBackReference
和@JsonManagedReference
。即使这样,我还是得到了无限递归
使用@JsonBackReference(“个人组织”)
上的@JsonBackReference(“个人组织”)
和@JsonManagedReference(“个人组织”)
上的个人组织
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注释的方式有问题,请告诉我。谢谢我以前遇到过这个问题。但是在将@JsonIgnore从私有字段移动到字段的getter之后,无限递归就消失了。所以我的猜测是@JsonIgnore在私有领域可能不起作用。然而,javadoc或jacksonjavajson处理器教程并没有提到这一点,所以我不能100%肯定。仅供参考。下面的链接说,您应该注释JSON工具用于遍历对象图的方法,以指示it忽略遍历 在我的例子中,我有两个相关的对象,比如这个产品ProductImage。因此,JSON解析器进入了一个无限循环,在下面的方法中没有@JsonIgnore注释
@JsonIgnore
public Product getImageOfProduct() {
return imageOfProduct;
}
在产品形象和
@JsonIgnore
public Set<ProductImage> getProductImages() {
return productImages;
}
@JsonIgnore
公共集getProductImages(){
返回产品图片;
}
在产品中
有了这个注释,一切都很顺利。我知道这个问题并不是专门针对SpringDataREST的,但我在SpringDataREST的上下文中遇到了这个异常,我想与大家分享问题所在。我有一个双向关系,涉及一个没有存储库的实体。创建存储库使循环消失。自Jackson 1.6以来,您可以使用两个注释来解决无限递归问题,而不会在序列化过程中忽略getter/setter:@JsonManagedReference和@JsonBackReference
有关更多详细信息,请参阅,这可能有点旧,但您可以在类级别添加@JsonIgnore,其中包含它应该忽略的所有属性。e、 g
@JsonIgnore("productImaes","...")
public class Product{ ...
}
有时,成员字段可能对其自身的同一类类型有内部引用,这可能导致
toJson
时出现无限递归
例如:您有一个成员字段Klass a
,而该Klass的类定义如下所示
class Klass {
Klass mySibling;
public toString() {
return "something" + mySibling.whateverMethod;
}
}
解决方案:重构成员字段,消除内部引用。Jackson通过调用getter处理反射。我也遇到过这样的情况,在它的类中有一个相同对象的getter。Jackson通过反复调用自己的getter,进入无限递归,吞噬堆栈。移除getter,然后修复它 我的忠告是:
如果要使用jackson转换对象,请不要保留引用同一对象的getter,就像单例一样。显然,从jackson 1.6开始,您可以使用和有效地解决无限递归问题 我将不详细介绍,但将您的类更改为以下格式应该可以解决问题
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;
}
公共类人物{
@OneToMany(targetEntity=PersonOrganization.class,cascade=CascadeType.ALL,fetch=FetchType.EAGER,mappedBy=“person”)
@列(nullable=true)
@JsonManagedReference
私人集合组织;
.....
}
公共阶级个人组织{
@manytone(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinColumn(name=“PERSONID”)
@JsonBackReference
私人;
}
基本上,Jackson使用编组过程将引用a的前向部分Set organization
转换为类似json的格式,然后查找引用的后向部分Person
,而不序列化它
Credits-&More info-此异常是因为构造函数字段不正确,请在类中再次检查构造函数属性,并检查映射是否正确 保留两个构造函数,第一个是零构造,第二个是带字段的构造函数,如果A有B&B有A,则两者都应包含super 这是一对一的关系,但形成循环关系 在任何类中,使用JustIgnore注释
class A
{
B b;
}
class B
{
@JsonIgnore
A a;
}
这也适用于其他关系,如一对多。对于我来说,我尝试过@JsonIgnore、@JsonManagedReference/@JsonBackReference,但在阅读本文和本文之前,没有任何效果
解决方案1是从fetch.LAZY改为fetch.EAGER,解决方案2使用的是
@JsonIgnoreProperties({“hibernateLazyInitializer”,“handler”})
,当然,在两种解决方案中都使用@JsonIgnore我现在可以给你一个大大的吻了。这解决了我的问题。在我的例子中,字段是受保护的。这还不够,我仍然有问题。注释getter而不是字段对我有效。WAS 8.5 JEE 6。我有两个存储库,但我仍然有一个循环。我找到了解决方案:我们需要在投影上使用@JsonManagedReference和@JsonBackReference(而不是在实体中)
class A
{
B b;
}
class B
{
@JsonIgnore
A a;
}