使用@OneToMany 和@ManyToOne 注释正在更新一个实体 table 但不是许多 table
Using @OneToMany and @ManyToOne annotations is updating one entity table but not the many table
我有一个 Spring restful API 使用 H2 数据库和 JPA 来填充一些表。我正在尝试设置一个具有字段 @OneToMany
的实体,而另一个实体对象是 @ManyToOne
。当我在 Postman 中发出 POST 请求时,我 sout
我的 Quiz quiz
即请求正文和字段符合预期。然而,当我登录到本地主机上的数据库时,只有 quiz_table
更新了正确的属性。
当我执行 POST 请求时,我在控制台中得到了这个输出
Hibernate: insert into quiz_table (answer, text, title, id) values (?, ?, ?, ?)
我的JSON请求正文是
{
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": ["2002", "2019"],
"answer": 1
}
服务器响应是
{
"id": 67,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 0,
"quiz": null,
"option": "2002"
},
{
"id": 0,
"quiz": null,
"option": "2019"
}
]
}
据我所知,"options"
的值正在传递给 List<Option>
这是我的控制器,带有此端点的映射
@PostMapping(path = "api/quizzes", produces = "application/json")
public Quiz addQuiz(@Valid @RequestBody Quiz quiz) {
quizRepository.save(quiz);
return quiz;
}
Quiz
class
@Component
@Entity(name = "quiz_table")
public class Quiz {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotBlank(message = "Title must not be blank")
private String title;
@NotBlank(message = "Text must not be blank")
private String text;
@Size(min = 2)
// @NotNull
@OneToMany(mappedBy = "quiz")
private List<Option> options;
@JsonIgnore
private int answer;
public Quiz() {}
public Quiz(String title, String text, List<Option> options, int answer) {
this.title = title;
this.text = text;
this.options = options;
this.answer = answer;
}
Option
class
@Component
@Entity(name = "options_table")
public class Option {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
@JoinColumn
private Quiz quiz;
private String option;
// for Jackson deserielization
public Option() {
}
/*public Option(Quiz quiz, String option) {
this.quiz = quiz;
this.option = option;
}*/
public Option(String option) {
this.option = option;
}
// getters/setters
编辑:实施建议后的异常 JSON 响应
{
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win
// ... continues for 4000 lines!
- 对于 JPA/Hibernate,您需要明确管理双向关系
@PostMapping(path = "api/quizzes", produces = "application/json")
public Quiz addQuiz(@Valid @RequestBody Quiz quiz) {
quiz.getOptions().forEach(option -> option.setQuiz(quiz));
quizRepository.save(quiz);
return quiz;
}
- 而且,你必须告诉 hibernate,当它管理
Quiz
、级联 Option
时
@Size(min = 2)
@OneToMany(mappedBy = "quiz", cascade = CascadeType.ALL)
private List<Option> options;
我有一个 Spring restful API 使用 H2 数据库和 JPA 来填充一些表。我正在尝试设置一个具有字段 @OneToMany
的实体,而另一个实体对象是 @ManyToOne
。当我在 Postman 中发出 POST 请求时,我 sout
我的 Quiz quiz
即请求正文和字段符合预期。然而,当我登录到本地主机上的数据库时,只有 quiz_table
更新了正确的属性。
当我执行 POST 请求时,我在控制台中得到了这个输出
Hibernate: insert into quiz_table (answer, text, title, id) values (?, ?, ?, ?)
我的JSON请求正文是
{
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": ["2002", "2019"],
"answer": 1
}
服务器响应是
{
"id": 67,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 0,
"quiz": null,
"option": "2002"
},
{
"id": 0,
"quiz": null,
"option": "2019"
}
]
}
据我所知,"options"
的值正在传递给 List<Option>
这是我的控制器,带有此端点的映射
@PostMapping(path = "api/quizzes", produces = "application/json")
public Quiz addQuiz(@Valid @RequestBody Quiz quiz) {
quizRepository.save(quiz);
return quiz;
}
Quiz
class
@Component
@Entity(name = "quiz_table")
public class Quiz {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotBlank(message = "Title must not be blank")
private String title;
@NotBlank(message = "Text must not be blank")
private String text;
@Size(min = 2)
// @NotNull
@OneToMany(mappedBy = "quiz")
private List<Option> options;
@JsonIgnore
private int answer;
public Quiz() {}
public Quiz(String title, String text, List<Option> options, int answer) {
this.title = title;
this.text = text;
this.options = options;
this.answer = answer;
}
Option
class
@Component
@Entity(name = "options_table")
public class Option {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@ManyToOne
@JoinColumn
private Quiz quiz;
private String option;
// for Jackson deserielization
public Option() {
}
/*public Option(Quiz quiz, String option) {
this.quiz = quiz;
this.option = option;
}*/
public Option(String option) {
this.option = option;
}
// getters/setters
编辑:实施建议后的异常 JSON 响应
{
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win a trophy?",
"options": [
{
"id": 2,
"quiz": {
"id": 1,
"title": "Tottenham Quiz",
"text": "When did Tottenham Hotspur last win
// ... continues for 4000 lines!
- 对于 JPA/Hibernate,您需要明确管理双向关系
@PostMapping(path = "api/quizzes", produces = "application/json")
public Quiz addQuiz(@Valid @RequestBody Quiz quiz) {
quiz.getOptions().forEach(option -> option.setQuiz(quiz));
quizRepository.save(quiz);
return quiz;
}
- 而且,你必须告诉 hibernate,当它管理
Quiz
、级联Option
时
@Size(min = 2)
@OneToMany(mappedBy = "quiz", cascade = CascadeType.ALL)
private List<Option> options;