Spring MVC - бесконечная рекурсия JSON - PullRequest
24 голосов
/ 27 января 2012

У меня такие двунаправленные отношения ...

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. Спасибо

Ответы [ 10 ]

40 голосов
/ 28 января 2012

Я сталкивался с этим раньше. Но после перемещения @JsonIgnore из частного поля в получатель поля бесконечная рекурсия исчезла. Так что мое дикое предположение состоит в том, что @JsonIgnore может не работать на частном поле. Однако, Javadoc или учебник JSON-процессора Jackson Java не упоминают об этом, поэтому я не могу быть уверен на 100%. Просто для вашей информации.

10 голосов
/ 10 мая 2012

Следующая ссылка говорит, что вы должны аннотировать метод, используемый инструментом JSON для обхода графа объекта, чтобы дать ему команду игнорировать обход.

http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/annotate/JsonIgnore.html

В моем случае у меня есть два объекта, связанных с этим Product <-> ProductImage. Таким образом, JSON-анализатор вошел в бесконечный цикл без аннотации @JsonIgnore для получения методов

@JsonIgnore
public Product getImageOfProduct() {
    return imageOfProduct;
}

в ProductImage и

@JsonIgnore
public Set<ProductImage> getProductImages() {
    return productImages;
}

в продукте.

С аннотацией все работает нормально.

5 голосов
/ 07 мая 2013

Я знаю, что этот вопрос не относится конкретно к Spring Data REST, но я столкнулся с этим исключением в контексте Spring Data REST и хотел рассказать, в чем проблема. У меня были двунаправленные отношения с участием объекта без хранилища. Создание хранилища заставило цикл исчезнуть.

4 голосов
/ 06 апреля 2014

Начиная с Jackson 1.6, вы можете использовать две аннотации для решения проблемы бесконечной рекурсии без игнорирования методов получения / установки во время сериализации: @JsonManagedReference и @ JsonBackReference.

Для получения дополнительной информации см. https://stackoverflow.com/a/18288939/286588

2 голосов
/ 05 июля 2017

Очевидно, что с версии 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, заднюю часть ссылки, и не сериализует его.

Кредиты - Курт Бурбаки & Дополнительная информация - http://keenformatics.blogspot.co.ke/2013/08/how-to-solve-json-infinite-recursion.html

1 голос
/ 22 сентября 2017

Если A имеет B & B, имеет A.

Это отношение один к одному , но оно образует круговое отношение.

В любом классе используйте аннотацию JustIgnore.

class A
{    
B b;    
}

class B
{    
@JsonIgnore
A a;
}

Это относится и к другим отношениям, таким как один ко многим.

0 голосов
/ 13 июля 2017

Это исключение из-за того, что ваше поле конструктора неверно, пожалуйста, проверьте ваши свойства конструкторов еще раз в ваших классах, и проверьте, правильно ли отображено отображение,

Оставьте два Конструктора, первый - нулевая конструкция, а второй - с полями, и оба должны содержать супер

0 голосов
/ 15 июня 2016

Джексон работает над Reflection, вызывая геттеров.У меня тоже была такая ситуация, когда у меня был получатель того же самого Объекта внутри его класса.Джексон пошел в бесконечную рекурсию, поглощая стек, неоднократно вызывая свой собственный метод получения.Удален геттер, затем он исправлен.

Мой совет: если вы хотите использовать Джексон для преобразования объекта, никогда не оставляйте геттеры, которые ссылаются на тот же объект, как в случае синглетонов.

0 голосов
/ 02 марта 2016

Иногда поле члена может иметь внутреннюю ссылку на тот же тип класса самого себя, что может вызвать бесконечную рекурсию при toJson.

Например: у вас есть поле члена Klass a, в то время как определение класса этого Klass приведено ниже.

class Klass {
    Klass mySibling;

    public toString() {
        return "something" + mySibling.whateverMethod;
    }
}

Решение: выполнить рефакторинг поля элемента, исключить внутреннюю ссылку.

0 голосов
/ 06 января 2016

Это может быть немного старым, но вы можете добавить @JsonIgnore на уровне класса со всеми свойствами, которые должны игнорироваться.например,

@JsonIgnore("productImaes","...")
public class Product{ ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...