Подтвердить что ты не робот

Spring Бесконечная рекурсия MVC - JSON

У меня двунаправленное отношение, подобное этому...

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. Благодаря

4b9b3361

Ответ 1

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

Ответ 2

В следующей ссылке указано, что вы должны аннотировать метод, используемый средством 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;
}

в продукте.

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

Ответ 3

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

Ответ 4

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

Подробнее см. fooobar.com/questions/27421/...

Ответ 5

По-видимому, с 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 p >

Ответ 6

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

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

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

class A
{    
B b;    
}

class B
{    
@JsonIgnore
A a;
}

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

Ответ 7

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

@JsonIgnore("productImaes","...")
public class Product{ ...
}

Ответ 8

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

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

class Klass {
    Klass mySibling;

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

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

Ответ 9

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

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

Ответ 10

для меня я пробовал @JsonIgnore, @JsonManagedReference/@JsonBackReference, но ничего не получалось, пока я не прочитал это исключение ["hibernateLazyInitializer"] решение 1 и это исключение ["hibernateLazyInitializer"]] 2

решение 1 должно перейти от fetch.LAZY к fetch.EAGER, а решение 2 использует @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"}), и, конечно, использовать @JsonIgnore в обоих решениях

Ответ 11

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

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