The scenario:
Java + springboot + thymeleaf. I have a question entity which has a @OneToMany relationship with an answer entity:
@Entity
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "question_gen")
@SequenceGenerator(name = "question_gen", sequenceName = "QUESTION_SEQ", allocationSize = 1)
private long questionId;
@Column
private String questionText;
@OneToMany(cascade = CascadeType.PERSIST)
@LazyCollection(LazyCollectionOption.FALSE)
private List<Answer> answers = new ArrayList<>();
@Column
private String correctAnswer;
@Column
private boolean approved;
@ManyToMany(cascade = CascadeType.PERSIST)
@LazyCollection(LazyCollectionOption.FALSE)
private List<Tag> tags;
public Question(String questionText, List<Answer> answers, String correctAnswer, boolean approved) {
super();
this.questionText = questionText;
this.answers = answers;
this.correctAnswer = correctAnswer;
this.approved = approved;
}
public Question(String questionText, List<Answer> answers, String correctAnswer, boolean approved, List<Tag> tags) {
super();
this.questionText = questionText;
this.answers = answers;
this.correctAnswer = correctAnswer;
this.approved = approved;
this.tags = tags;
}
public Question() {
super();
}
standard getter and setter etc follow
@Entity
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "answer_gen")
@SequenceGenerator(name = "answer_gen", sequenceName = "ANSWER_SEQ", allocationSize = 1)
private long answerId;
@Column
private String answerText;
public Answer(String answerText) {
super();
this.answerText = answerText;
}
public Answer() {
super();
}
The controller
@GetMapping("/EditQuestion/{questionId}")
public ModelAndView editQuestion(@PathVariable("questionId") long questionId, ModelAndView modelAndView) {
Optional<Question> question = questionService.retrieveOne(questionId);
modelAndView.addObject("question", question.get());
modelAndView.addObject("allTags", tagService.retrieveAll());
modelAndView.addObject("answers", question.get().getAnswers());
if (question.isPresent()) {
modelAndView.setViewName("editQuestion");
return modelAndView;
}
return modelAndView;
}
@PostMapping("/EditQuestionSubmit")
public ModelAndView editQuestionSubmit(ModelAndView modelAndView, Question question) {
if (questionService.update(question)) {
modelAndView.addObject("allQuestions", questionService.retrieveAll());
modelAndView.setViewName("allQuestions");
return modelAndView;
}
modelAndView.setViewName("allQuestions");
return modelAndView;
}
listing, retrieving one and adding through a thymeleaf all working but when I try to edit the list just gets nulls
The thymeleaf:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Edit Question Details</title>
</head>
<body>
<h1>Edit Question Details</h1>
<form action="#" th:action="@{/EditQuestionSubmit}"
th:object="${question}" method="post">
<div>
<p>
<label th:if="${questionText} == null"
th:text=" ' Edit your question'" /></label>
</p>
<p>
<input type="text" th:field="*{questionText}" />
</p>
</div>
<div>
<p>
<label th:text=" 'enter answers A-D for this question ' "></label>
</p>
<p>
<input type="text" th:field="*{answers}" value="${answerId}" />
</p>
</div>
<input type="text" th:each="answer : ${answers}" th:id="answerId" th:text="${answer.answerText}"
th:value="${answer.answerId}" name="answers" th:field="*{answers}" />
</div>
<div>
<p>
<label th:if="${correctAnswer} == null"
th:text="'Select the correct answer for this question'" /></label>
</p>
<p>
<select id="correctAnswer" name="correctAnswer"
th:value="${question.correctAnswer}"
th:selected="${question.correctAnswer}">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
</p>
</div>
<div>
<p>
<label>select relevant tags</label>
<p>
<select id="tagId" multiple name="tags"
th:selected="${question.tags}">
<option th:each="tag : ${allTags}" th:value="${tag.tagId}"
th:text="${tag.name}"></option>
</select>
</p>
</div>
<div>
<p>
<button type="submit">Edit Question</button>
</p>
</div>
<input type="hidden" th:field="*{questionId}" value="${questionId}" />
</form>
</body>
</html>
all other fields are working, I've tried a lot of different things but no joy, and input greatly appreciated
the solution is multi part. First I added a wrapper class
public class AnswerWrapper {
private List<Answer> answers;
public void addAnswer(Answer answer, Question question) {
int index = (int) question.getQuestionId();
answers = question.getAnswers();
this.answers.add(index, answer);
}
}
Then I updated the controller
@GetMapping("/EditQuestion/{questionId}")
public ModelAndView editQuestion(@PathVariable("questionId") long questionId, ModelAndView modelAndView) {
Optional<Question> question = questionService.retrieveOne(questionId);
List<Answer> answers = question.get().getAnswers();
AnswerWrapper answerWrapper = new AnswerWrapper();
for (int i = 0 ; i >= answers.size(); i++) {
Answer answer = answers.get(i);
answer.setAnswerId(answer.getAnswerId());
answerWrapper.addAnswer(answer, question.get());
}
modelAndView.addObject("question", question.get());
modelAndView.addObject("allTags", tagService.retrieveAll());
modelAndView.addObject("answers", question.get().getAnswers());
if (question.isPresent()) {
modelAndView.setViewName("editQuestion");
return modelAndView;
}
return modelAndView;
}
no changes needed for the PostMapping Then I updated the thymeleaf
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Edit Question Details</title>
</head>
<body>
<h1>Edit Question Details</h1>
<form action="#" th:action="@{/EditQuestionSubmit}"
th:object="${question}" method="post">
<div>
<p>
<label th:if="${questionText} == null"
th:text=" ' Edit your question'" /></label>
</p>
<p>
<input type="text" th:field="*{questionText}" />
</p>
</div>
<div>
<p>
<label th:text=" 'enter answers A-D for this question ' "></label>
</p>
<div th:each="answer, answerIndex: *{answers}">
<td><input
th:field="*{answers[__${answerIndex.index}__].answerText}"
th:value="${answer.getAnswerId()}" /></td> <input hidden
th:name="|answers[${answerIndex.index}].answerId|"
th:value="${answer.getAnswerId()}" />
</div>
<div>
<p>
<label th:if="${correctAnswer} == null"
th:text="'Select the correct answer for this question'" /></label>
</p>
<p>
<select id="correctAnswer" name="correctAnswer"
th:value="${question.correctAnswer}"
th:selected="${question.correctAnswer}">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
</select>
</p>
</div>
<div>
<p>
<label>select relevant tags</label>
<p>
<select id="tagId" multiple name="tags"
th:selected="${question.tags}">
<option th:each="tag : ${allTags}" th:value="${tag.tagId}"
th:text="${tag.name}"></option>
</select>
</p>
</div>
<div>
<p>
<button type="submit">Edit Question</button>
</p>
</div>
<input type="hidden" th:field="*{questionId}" value="${questionId}" />
</form>
</body>
</html>
and now all is well
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.