[英]Nested one-to-many problem in spring data JPA
表格:
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獲得一個Survey時,如下所示:
@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."
}]
}]
}
請告訴我如何解決這個問題?
您正在使用fetch = FetchType.EAGER
兩者
private List<SurveyQuestion> questions;
和
private List<SurveyQuestionOption> options;
因此,默認情況下,您總是在這里獲取整個樹。
現在的關鍵是,您將這些依賴項聲明為List
。 這意味着有序但允許重復。 在這里,每個選項都有一個重復的問題。
嘗試使用Set
或SortedSet
避免重復。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.