SpringMVC-JSON无限递归

SpringMVC-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; ..... }

我有这样的双向关系

Person.java

 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;
}