我是SPING和Web开发的新手。
我正在开发测试任务-报价书(未经授权)。我有两个实体:Quote和Author。有代码:
@Entity
@Table(name="authors")
public class Author {
@Id
@SequenceGenerator(name="author_id_seq", sequenceName="author_id_seq", allocationSize=1)
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "author_id_seq")
@Column(name = "id")
private long id;
@Column(name = "nick_name")
private String nickName;
public Author() {
}
public Author(long id, String nickName) {
this.id = id;
nickName = nickName;
}
/*
Getters and Setters
*/
}
报价:
@Entity
@Table(name = "quotes")
public class Quote {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
@SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
@Column(name = "id")
private long id;
@Column(name = "content")
private String content;
// @Temporal(TemporalType.DATE)
@Column(name = "date")
private LocalDate date;
@ManyToOne
@JoinColumn(name = "author")
private Author author;
public Quote() {
}
public Quote(long id, String content, LocalDate date, Author author) {
this.id = id;
this.content = content;
this.date = date;
this.author = author;
}
/*
Getters and Setters
*/
}
我的Thymeleaf模板包含带有两个输入字段的表单(quote.content和quote.author.nickName),并使用现有作者进行选择。我想看看这种行为,当我填写作者,内容的输入,并且如果authors表中不存在author时,我的应用程序将在表中添加行,该行由输入的nickName和生成的id中的值指定。但是问题是从Thymeleaf模板为我获得意想不到的结果。模板将带有作者的Quote对象传递给控制器,该对象的昵称为null而不是我输入的值。我的表单中有thymeleaf模板代码:
<form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
<div class="form-row">
<div class="form-group col-md-3">
<label class="sr-only" for="inputNick">Nick Name</label>
<!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
<input type="text" class="form-control" id="inputNick" th:field="*{author.nickName}"
placeholder="enter Nick Name">
</div>
<div class="form-group col-md-6">
<select id="nickNames">
<th:block th:each="author : ${allAuthors}">
<option th:text="${author.nickName}">Nick Name</option>
</th:block>
</select>
</div>
<div class="form-group col-md-12">
<label for="postContent">Your Quote:</label>
<input type="text" class="form-control" id="postContent" th:field="*{content}"
placeholder="quote text">
</div>
</div>
<div class="form-group col-md-2">
<input type="submit" value="Add Quote"/>
</div>
<div class="form-group col-md-2">
<input type="reset" value="Reset"/>
</div>
</form>
控制器方法:
@GetMapping("/newQuote")
public String showAuthors(Model model){
model.addAttribute("allAuthors",authorService.findAll());
model.addAttribute("quote", new Quote());
return "newQuote";
}
@PostMapping("/newQuote")
public String addQuote (@ModelAttribute Quote quote) {
quote.setDate(LocalDate.now());
quoteRepository.save(quote);
return "redirect:/";
我尝试过:
我知道我可以使用字段昵称而不是作者字段创建DTO类,并在控制器的后映射方法中将其转换为我的实体类。但我认为这是“不良做法”的方式。我认为,当尝试更改作者对象并将其从百里香叶传递给控制器时,我可能采取了错误的步骤。而且我想,在这种情况下没有办法实现这种逻辑。我不知道真相在哪里。请帮我找到它。
P.S:对不起,我的英语不好
答案 0 :(得分:0)
因此,答案是询问如何添加引号及其作者。使用选择方法是不可能的,因为我们的作者不存在。实现此目的的简单方法是更改报价实体,并将@Cascade(CascadeType.PERSIST)
添加到报价的作者字段中。这将自动为作者保留您的报价。
这些就是完成此操作所需的代码更改。
更新
由于最后一个解决方案不起作用,我们将尝试向控制器发送一个附加参数,以避免收到空值,而不是作者的昵称。
控制器
@PostMapping("/newQuote")
public String addQuote (@ModelAttribute Quote quote,
@RequestParam("nickName") String nickName) {
// This will automatically persist your quote and it's author.
quote.setDate(LocalDate.now());
Author author = new Author();
author.setNickName(nickName);
quoteRepository.save(quote);
}
报价实体
@Entity
@Table(name = "quotes")
public class Quote {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
@SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
@Column(name = "id")
private long id;
@Column(name = "content")
private String content;
@Column(name = "date")
private LocalDate date;
@ManyToOne
@Cascade(CascadeType.PERSIST)
@JoinColumn(name = "author")
private Author author;
// Getters and Setters
}
重要,请确保注意我们正在向作者字段添加新的注释@Cascade(CascadeType.PERSIST)
。
HTML
在这里,我们将删除不必要的选择。
<form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
<div class="form-row">
<div class="form-group col-md-3">
<label class="sr-only" for="inputNick">Nick Name</label>
<!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
<input type="text" name="nickName" class="form-control" id="inputNick" placeholder="enter Nick Name"/>
</div>
<div class="form-group col-md-12">
<label for="postContent">Your Quote:</label>
<input type="text" class="form-control" id="postContent" th:field="*{content}" placeholder="quote text"/>
</div>
</div>
<div class="form-group col-md-2">
<input type="submit" value="Add Quote"/>
</div>
<div class="form-group col-md-2">
<input type="reset" value="Reset"/>
</div>
</form>