IllegalStateException при создании вложенных объектов - PullRequest
0 голосов
/ 02 февраля 2019

У меня есть вложенная иерархия для сущностей,
Опрос
-Вопрос []
- Ответ []

И у меня возникают проблемы с ее сохранением.До того как я добавил @PrePersist методы, он работал почти нормально, дочерние объекты имели пустой внешний ключ для родителей.Я нашел другой похожий вопрос, который предложил использовать @PrePersist для решения этой проблемы, поэтому я попытался, но это вызывает

java.lang.IllegalStateException: Cannot call sendError() after the response has been committed

JSON, который возвращается после вызова этого метода выглядитчто {"id":1,"title":"Test Survey","description":null,"endingDateTime":null,"questions":[{"id":1,"content":"Test Question","survey":{"id":1,"title":"Test Survey","description":null,"endingDateTime":null,"questions":[{"id":1,"content":"Test Question","survey" .... и оно повторяется снова и снова.

Если это важно в этом случае, я использую Spring Boot 2.1.2 и Java 11.

@Entity
@Table(name = "survey")
public class Survey implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "survey_id")
    private Long id;

    @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "survey")
    private List<Question> questions = new ArrayList<>();

    @PrePersist
    private void prePersist() {
        questions.forEach(q -> {
            q.setSurvey(this);
        });
    }
}

@Entity
@Table(name = "question")
public class Question implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "question_id")
    private Long id;
    private String content;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "survey_id")
    private Survey survey;

    @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "question")
    private List<Answer> answers = new ArrayList<>();

    @PrePersist
    private void prePersist() {
        answers.forEach(a -> {
            a.setQuestion(this);
        });
    }
}

@Entity
public class Answer implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "answer_id")
    private Long id;
    private String content;
    private Integer votes;

    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "question_id")
    private Question question;
}

   public Survey createSurvey() {
        Answer answerA = Answer.builder()
                .content("A").build();
        Answer answerB = Answer.builder()
                .content("B").build();
        Question question = Question.builder()
                .content("Test Question")
                .answers(Arrays.asList(answerA, answerB))
                .build();
        Survey survey = Survey.builder()
                .title("Test Survey")
                .questions(Arrays.asList(question))
                .build();
        return surveyRepository.save(survey);
    }

Edit # Если это помогает, я проверяю это с помощью GET.Конец стека трассировки Я получаю Cannot render error page for request [/result] and exception [Could not write JSON: Infinite recursion (StackOverflowError)

Не уверен, почему это происходит, хотя ...

Edit # После входа в консоль H2, я вижу опрос, вопрос и 2 ответа.Никто из них не имеет отношения от ребенка к родителю.

1 Ответ

0 голосов
/ 02 февраля 2019

Решение было действительно простым, на всех @OneToMany я добавил @JsonManagedReference

 @OneToMany(cascade = CascadeType.PERSIST, mappedBy = "question")
 @JsonManagedReference
 private List<Answer> answers = new ArrayList<>();

И на @ManyToOne я добавил JsonBackReference

 @ManyToOne(cascade = CascadeType.PERSIST)
 @JoinColumn(name = "survey_id")
 @JsonBackReference
 private Survey survey;
...