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. Благодаря
Ответы
Ответ 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 для преобразования объекта, никогда не держите геттеры, которые ссылаются на один и тот же объект, например, в случае одиночных чисел.