Я пытаюсь сохранить двунаправленную связь между двумя сущностями 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)
Я не знаю, правильно ли я это делаю, но я не могу найти другой способ сделать это.
Пожалуйста, будем рады любой помощи.