表格:
survey(id, title);
survey_question(id, survey_id, title);
survey_question_option(id, survey_question_id, content)
实体:
@Entity
public class Survey implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
@OneToMany(mappedBy = "survey", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
private List<SurveyQuestion> questions;
}
@Entity
public class SurveyQuestion implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JoinColumn(nullable = false)
@ManyToOne
@JsonIgnore
private Survey survey;
private String title;
@OneToMany(mappedBy = "surveyQuestion", fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
private List<SurveyQuestionOption> options;
}
@Entity
public class SurveyQuestionOption implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@JoinColumn(nullable = false)
@ManyToOne
@JsonIgnore
private SurveyQuestion surveyQuestion;
private String content;
}
现在添加调查
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Survey create(@RequestBody Survey survey) {
return repository.save(survey);
}
请求正文中的JSON
{
"title": "I'm a survey!",
"questions": [{
"title": "I'm a question!",
"options": [{
"content": "I'm an option."
},
{
"content": "I'm an option."
},
{
"content": "I'm an option."
},
{
"content": "I'm an option."
}]
},
{
"title": "I'm a question!",
"options": [{
"content": "I'm an option."
},
{
"content": "I'm an option."
},
{
"content": "I'm an option."
},
{
"content": "I'm an option."
}]
}]
}
成功,然后是这样的表:
调查:
id title
---------------------------------------
46 I'm a survey!
survey_question:
id survey_id title
---------------------------------------
34 46 I'm a question!
35 46 I'm a question!
survey_question_option:
id survey_question_id content
---------------------------------------
17 34 I'm an option!
18 34 I'm an option!
19 34 I'm an option!
20 34 I'm an option!
21 35 I'm an option!
22 35 I'm an option!
23 35 I'm an option!
24 35 I'm an option!
现在,当我按页面获取所有调查
@GetMapping
public Page<Survey> findAll(Pageable page) {
return repository.findAll(page);
}
回答正确,有2个问题,每个问题4个选择
{
"content": [{
"id": 46,
"title": "I'm a survey!",
"questions": [{
"id": 34,
"title": "I'm a question!",
"options": [{
"id": 17,
"content": "I'm an option."
},
{
"id": 18,
"content": "I'm an option."
},
{
"id": 19,
"content": "I'm an option."
},
{
"id": 20,
"content": "I'm an option."
}]
},
{
"id": 35,
"title": "I'm a question!",
"options": [{
"id": 21,
"content": "I'm an option."
},
{
"id": 22,
"content": "I'm an option."
},
{
"id": 23,
"content": "I'm an option."
},
{
"id": 24,
"content": "I'm an option."
}]
}]
}],
"page": 1,
"size": 20,
"totalPages": 1,
"totalCount": 1
}
但是,当我像这样通过ID获得一份问卷调查时:
@GetMapping("/{id:\\d+}") // 46
public Survey get(@PathVariable Long id) {
return repository.findById(id).orElse(null);
}
回答让我感到困惑,共有8个问题
{
"id": 46,
"title": "1111111111111",
"questions": [{
"id": 34,
"title": "I'm a question!",
"options": [{
"id": 17,
"content": "I'm an option."
},
{
"id": 18,
"content": "I'm an option."
},
{
"id": 19,
"content": "I'm an option."
},
{
"id": 20,
"content": "I'm an option."
}]
},
{
"id": 34,
"title": "I'm a question!",
"options": [{
"id": 17,
"content": "I'm an option."
},
{
"id": 18,
"content": "I'm an option."
},
{
"id": 19,
"content": "I'm an option."
},
{
"id": 20,
"content": "I'm an option."
}]
},
{
"id": 34,
"title": "I'm a question!",
"options": [{
"id": 17,
"content": "I'm an option."
},
{
"id": 18,
"content": "I'm an option."
},
{
"id": 19,
"content": "I'm an option."
},
{
"id": 20,
"content": "I'm an option."
}]
},
{
"id": 34,
"title": "I'm a question!",
"options": [{
"id": 17,
"content": "I'm an option."
},
{
"id": 18,
"content": "I'm an option."
},
{
"id": 19,
"content": "I'm an option."
},
{
"id": 20,
"content": "I'm an option."
}]
},
{
"id": 35,
"title": "I'm a question!",
"options": [{
"id": 21,
"content": "I'm an option."
},
{
"id": 22,
"content": "I'm an option."
},
{
"id": 23,
"content": "I'm an option."
},
{
"id": 24,
"content": "I'm an option."
}]
},
{
"id": 35,
"title": "I'm a question!",
"options": [{
"id": 21,
"content": "I'm an option."
},
{
"id": 22,
"content": "I'm an option."
},
{
"id": 23,
"content": "I'm an option."
},
{
"id": 24,
"content": "I'm an option."
}]
},
{
"id": 35,
"title": "I'm a question!",
"options": [{
"id": 21,
"content": "I'm an option."
},
{
"id": 22,
"content": "I'm an option."
},
{
"id": 23,
"content": "I'm an option."
},
{
"id": 24,
"content": "I'm an option."
}]
},
{
"id": 35,
"title": "I'm a question!",
"options": [{
"id": 21,
"content": "I'm an option."
},
{
"id": 22,
"content": "I'm an option."
},
{
"id": 23,
"content": "I'm an option."
},
{
"id": 24,
"content": "I'm an option."
}]
}]
}
请告诉我如何解决此问题?
答案 0 :(得分:1)
您同时使用fetch = FetchType.EAGER
private List<SurveyQuestion> questions;
和
private List<SurveyQuestionOption> options;
因此,默认情况下,您总是在这里获取整棵树。
现在,这里的关键是您将那些依赖项声明为List
。这意味着有序但允许重复。在这里,每个选项都有一个重复的问题。
尝试使用Set
或SortedSet
来避免重复。