Вопрос:

Как разорвать бесконечный родительско-дочерний цикл в Hibernate

hibernate infinite-loop bidirectional-relation

135 просмотра

2 ответа

325 Репутация автора

У меня есть приложение со страницами, и у каждого из них могут быть дочерние страницы:

Page.java

public class Page{
  ...
  @Nullable
  @ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  private Page parentPage;

  @OneToMany(fetch = FetchType.EAGER, mappedBy = "parentPage")
  private List<Page> childPages;
  ...
}

Я хочу отобразить ссылку << Back to parent pageна каждой странице и иметь ссылки на все ее дочерние элементы:

view-page.html

<div ng-if="currentPage.parentPage">
  <a href="#/view-page?pageId={{currentPage.parentPage.id}}">Back to {{currentPage.parentPage.title}}</a>
</div>
...
<div ng-repeat="row in currentPage.childPages">
  <a href="#!/view-page?pageId={{row.id}}">{{row.title}}</a>
</div>

Это вызывает бесконечный цикл parent - child - parent - ...

Я попытался с @JsonIgnore, но затем я теряю информацию, которая мне нужна (будь то родитель или ребенок). Я также попытался аннотировать родителя с помощью @JsonManagedReferenceи списка дочерних страниц с помощью @JsonBackReference. Тогда я мог видеть родителей, но не детей. Следующим моим шагом будет попытка написать собственный сериализатор.

Поэтому мой вопрос: есть ли у кого-нибудь идея, как получить parentPageсвойство и при этом иметь возможность видеть детей, не попадая в бесконечный цикл child-parent-child-parent ...?

Автор: vtomic85 Источник Размещён: 10.01.2018 05:35

Ответы (2)


0 плюса

325 Репутация автора

Решение

Я нашел решение. В одном из отношений я мог бы использовать @JsonIgnore. В другом случае мне нужно было использовать собственный сериализатор, где я не буду загружать детей.

Автор: vtomic85 Размещён: 10.01.2018 05:58

0 плюса

3 Репутация автора

У меня такая же проблема. Существует способ создания пользовательских методов получения для parentPage и childPages, чтобы избежать бесконечного цикла.

Единственное условие, чтобы это работало, это то, что у вас есть только 2 уровня отношений, то есть первая группа страниц, которые являются мастер-страницами и не имеют родительского набора, и вторая группа страниц, которые являются дочерними по отношению к тем из первой группы.

Когда вам нужно получить доступ к родительской странице дочерней страницы (this.parentPage), вам не нужны ее дочерние страницы. Метод получения родительской страницы просто удаляет дочерние страницы, чтобы избежать бесконечного цикла.

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

public Page getParentPage() {
    if (this.parentPage != null) {
        // when accessing parent page, we don't need its children
        // as we can get children by accessing page itself
        this.parentPage.childPages = null;
    }
    return this.parentPage;
}

public List<Page> getChildPages() {
    if (this.parentPage != null) {
        // we have parent page set which means this
        // is a child page and we don't need children of children
        return null;
    }
    return this.childPages;
}
Автор: horvoje Размещён: 03.05.2019 10:43
Вопросы из категории :
32x32