簡體   English   中英

Spring Data JPA中的嵌套一對多問題

[英]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 這意味着有序但允許重復。 在這里,每個選項都有一個重復的問題。

嘗試使用SetSortedSet避免重復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM