Сохранение двунаправленной связи «один ко многим» между двумя объектами с использованием формы Thymeleaf - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь сохранить двунаправленную связь между двумя сущностями Quiz и Question, где @One сторона (Quiz) - это th:object формы Thymeleaf.

Итак, это сущность Quiz:

@Data
@ToString(exclude = { "subject", "questions" })
@Entity
@Table(name = "quiz", uniqueConstraints = @UniqueConstraint (columnNames="id_quiz"))
public class Quiz implements Serializable {

    private static final long serialVersionUID = 7899292643417556205L;

    @Id
    @Column(name = "id_quiz")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idQuiz;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "subject_code", referencedColumnName = "code", nullable = false)
    private Subject subject;

    @JsonIgnore
    @OneToMany(mappedBy = "quiz", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<Question> questions = new HashSet<>();

    public Quiz() {
        addQuestion(new Question());
    }

    public void addQuestion(Question question) {
        this.questions.add(question);
        question.setQuiz(this);
    }

    public void removeQuestion(Question question) {
        this.questions.remove(question);
        question.setQuiz(this);
    }
}

А это сущность Question:

@Data
@ToString(exclude = { "quiz", "answers" })
@Entity
@Table(name = "question", uniqueConstraints = @UniqueConstraint (columnNames="id_question"))
public class Question implements Serializable {

    private static final long serialVersionUID = -8286865818098612133L;

    @Id
    @Column(name = "id_question")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idQuestion;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "quiz_id", referencedColumnName = "id_quiz", nullable = false)
    private Quiz quiz;

    @Column(name = "question")
    @NotNull
    private String question;
}

Методы контроллера для GET и POSTформа:

    @GetMapping("/quiz")
    public String quizPage(@RequestParam(name = "edit", required = false) Integer quizId, Model model,
            HttpSession session) {

        if(quizId != null) {
            model.addAttribute("edit", true);
        }

        Quiz quiz = (quizId == null ? new Quiz() : quizService.find(quizId));

        model.addAttribute("quiz", quiz);
        model.addAttribute("questions", quiz.getQuestions());
        int teacherNiu = (int) session.getAttribute(SessionConstants.USER_NIU);
        model.addAttribute("subjects", subjectService.getSubjectsByUser(teacherNiu));

        return "teacher/quiz";
    }

    @PostMapping("/process-quiz")
    public String processQuiz(@RequestParam("publish") boolean publish, @Valid @ModelAttribute Quiz quiz) {
        quiz.setEnabled(publish);
        quizService.save(quiz);

        return "redirect:/teacher";
    }

До сих пор я пытался включить в форму свою коллекцию @Many как th:field и связать ее поля с пометкой *{}:

<form th:object="${quiz}" th:action="@{/teacher/process-quiz}" method="POST">
    <div th:each="question, iter : ${questions}" th:id="${'question-' + iter.index}">
        <input type="text" th:field="*{questions[__${iter.index}__].question}" required />
    </div>
</form>

Но когда я пытаюсь отправить форму, я получаю следующую ошибку: org.hibernate.AssertionFailure: null id in cat.uab.ulearning.db.model.Quiz entry (don't flush the Session after an exception occurs)

Я не знаю, правильно ли я это делаю, но я не могу найти другой способ сделать это.

Пожалуйста, будем рады любой помощи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...