【问题标题】:Using @OneToMany and @ManyToOne annotations is updating one entity table but not the many table使用 @OneToMany 和 @ManyToOne 注释是更新一个实体表,而不是许多表
【发布时间】:2020-07-18 15:08:26
【问题描述】:

我有一个 Spring RESTful API,它使用 H2 数据库和 JPA 来填充一些表。我正在尝试使用字段@OneToMany 设置一个实体,而另一个实体对象是@ManyToOne。当我在 Postman 中发出 POST 请求时,我 sout 我的 Quiz quiz 这是请求正文,字段与预期一致。然而,当我在 localhost 上登录数据库时,只有 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


@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

@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!

【问题讨论】:

  • 您是否尝试添加级联选项?我认为这就是您无法保存子实体的原因。
  • 我完全忽略了这一点。我猜没有默认设置?

标签: java spring jpa orm h2


【解决方案1】:
  • 使用 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;

【讨论】:

  • 它成功了,谢谢。我完全监督,CascadeType 被教授,但我不明白它必须明确声明。我虽然得到了一个不寻常的 JSON 响应,但它似乎是在响应中递归地添加返回的测验。我将在主帖中发布一个 sn-p。
  • 这不是休眠问题。那是杰克逊的问题。看到这个答案stackoverflow.com/questions/62623483/…
  • 如果遇到困难请告诉我
猜你喜欢
  • 2012-10-02
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
相关资源
最近更新 更多