【问题标题】:SpringBoot_JPA: OneToMany (bidirectional) not inserting foreign key in child tableSpringBoot_JPA:OneToMany(双向)不在子表中插入外键
【发布时间】:2017-05-23 07:59:44
【问题描述】:

SpringBoot 版本:1.4.2.RELEASE MySQL 版本:5.7.16 龙目岛

我有两个实体类 Question 和 Options,其中 Question 表中的 question_id 是 Question_Option 表中的外键。

问题实体

@Entity
@Table(name = "questions")
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Getter
@Setter
private int questionId;
@Getter
@Setter
@OneToMany(mappedBy = "question",fetch=FetchType.LAZY,   cascade=CascadeType.ALL)
private List<Option> option;

选项实体

@Entity
@Table(name = "questions_options")
public class Option {
@Id
@GeneratedValue
@Getter
@Setter
private int id;
@Getter
@Setter
private String optionsId;
@Getter
@Setter
 private String optionText;
@ManyToOne
@JoinColumn(name="questionId")
@Getter
@Setter
private Question question;
}

问题陈述 当我尝试 POST 时,外键 (question_id) 未插入选项表中。

Hibernate: insert into questions (questionId, LastUpdate, active, createTime, questionText, questionType) values (default, ?, ?, ?, ?, ?)
Hibernate: insert into questions_options (id, lastUpdate, optionText, optionsId, questionId) values (default, ?, ?, ?, ?)
Hibernate: insert into questions_options (id, lastUpdate, optionText, optionsId, questionId) values (default, ?, ?, ?, ?)

Hibernate:插入 questions_options(id、lastUpdate、optionText、optionsId、questionId)值(默认、?、?、?、?)

我是如何解决这个问题的? 我将问题实体更改为

@Getter
@Setter
@OneToMany(fetch=FetchType.LAZY, cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REMOVE})
@JoinColumn(name="questionId")
@NotNull
private List<Option> option;

和选项

@ManyToOne
@Getter
@Setter
@JoinColumn(name="questionId")
private Question question;

但我想知道为什么第一种方法不起作用以及我做错了什么。

【问题讨论】:

  • 您的第二种方法可能有效,但它是错误的。将其还原为原始映射并确保在保存之前设置关系的双方,即确保您已调用 option.setQuestion(question);
  • 艾伦是正确的。即使使用级联(Cascading.ALL),Option 方仍然拥有关系,并且外键的值取自 Option 的问题成员(由问题上的 mappedBy="question" 指定)。
  • 感谢@Alan Hay 和@Michal。我将关系更改为单向(通过从选项 Entity 中删除问题关系),它就起作用了。回到我的实际问题,我如何确保调用 option.setQuestion(question) ?我认为 Cascade.ALL 会解决这个问题。是否有任何注释可以强制执行? (对不起,我是新手:()
  • @Alan setting option.setquestion() throughs 无法添加或更新子行:外键约束失败

标签: hibernate jpa spring-boot spring-web


【解决方案1】:

试试下面的关系,它应该可以工作。

问题实体

@OneToMany(mappedBy = "question",fetch=FetchType.LAZY,cascade=CascadeType.ALL, targetEntity = Option.class)
private List<Option> option

选项实体

@ManyToOne
@JoinColumn(name = "questionId")
private Question question;

【讨论】:

    【解决方案2】:

    在控制器类中应该是这样的。

    @PostMapping("/question")
    public question addQuestion(@RequestBody Question question) {
    
        if( question.getOption().size() > 0 )
        {
            question.getOption().stream().forEach( option -> {
                option.setQuestion( question );
            } );
        }
    
       // You can save this question object now using the repository instance autowired.
        return question;
    }
    
    

    还有一点,在Option类实体中,需要添加@JsonIgnore注解,避免递归获取

    @ManyToOne
    @Getter
    @Setter
    @JoinColumn(name="questionId")
    @JsonIgnore
    private Question question;
    

    【讨论】:

      猜你喜欢
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多