简体   繁体   English

tb_child 中的外键是 null,具有双向一对多关系

[英]Foreign-key in tb_child is null with bidirectional one-to-many relationship

I´m creating my first Spring Boot application with the Java Persistence API to write to and read from a postgres database.我正在使用 Java 持久性 API 创建我的第一个 Spring 引导应用程序,以写入和读取 postgres 数据库。 I´ve looked through many tutorials and posts to figure out my exact problem and it seems like I currently have a bidirectional one-to-many relationship with two entities ( Parent and Child ), but the foreign-key of the child column is always null when I write to the database.我浏览了许多教程和帖子以找出我的确切问题,似乎我目前与两个实体( ParentChild )具有双向一对多关系,但child列的外键始终是null当我写入数据库时。

ParentEntity:父实体:

@Entity
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_parent")
public class Parent {
    @Schema(description = "id of the parent")
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Schema(description = "child-list of the application")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
    private Set<Child> children;
}

ChildEntity:子实体:

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "tb_child")
public class Child{
    @Schema(description = "id of the child")
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @JsonBackReference
    @ManyToOne(targetEntity = Parent.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id", referencedColumnName = "id", updatable = true, insertable = true)
    private Parent parent;
}

ParentService:家长服务:

...
    @Override
    public Parent create(Parent parent) {
        log.info("save new parent: {}", parent);
        return parentRepo.save(parent);   // the repo is an interface that extends the JpaRepository
    }
...

After invoking the create method, I have a parent row in the tb_parent with a generated id and one or more child rows in the tb_child with a generated id and a null value for the parent_id column.调用create方法后,我在 tb_parent 中有一个具有生成idparent行,在tb_parent中有一个或多child行,具有生成的idparent_idnull tb_child

Even though I´m able to find lots of posts describing a similar issue, I wasn´t yet able to find a solution that works for me.尽管我能找到很多描述类似问题的帖子,但我还没有找到适合我的解决方案。

Update #1:更新#1:

A common suggestion is to manually set the parent object in all child elements.一个常见的建议是在所有child元素中手动设置parent object。 However, this results in a Stackoverflow Exception due to the circular structure.但是,由于循环结构,这会导致 Stackoverflow 异常。

    public void setChildren(Set<Child> children) {
        children.forEach(child -> child.setParent(this));
        this.children = children;
    }

Additionally, it kinda feels off because almost everything is managed automatically by the JPA Annotations and then you have to manually sync the data.此外,感觉有点不对劲,因为几乎所有内容都由 JPA 注释自动管理,然后您必须手动同步数据。

Thanks to Georgy Lvov I was able to find the most effective solution.感谢Georgy Lvov ,我能够找到最有效的解决方案。 I had to do the following steps:我必须执行以下步骤:

  1. remove the @Data annotation as suggested by Georgy Lvov (Thank you so much,) This basically avoids the generated getter and setter methods for all attributes and the methods equals(), hashCode().按照Georgy Lvov的建议删除@Data注释(非常感谢,)这基本上避免了为所有属性生成的 getter 和 setter 方法以及方法 equals()、hashCode()。 and toString() by Lombok which caused the Stackoverflow Exception. Lombok 的 toString() 导致 Stackoverflow 异常。
  2. annotate the Set<Child> children;注释Set<Child> children; variable in the Parent class with the @JsonManagedReference annotation.带有@JsonManagedReference注释的Parent class 中的变量。 see below:见下文:
    @JsonManagedReference
    @Schema(description = "child-list of the application")
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
    private Set<Child> children;
  1. annotate the private Parent parent;注释private Parent parent; in the Child class with the @JsonBackReference annotation.在带有@JsonBackReference注释的Child class 中。 see below:见下文:
    @JsonBackReference
    @ManyToOne(targetEntity = Parent.class, fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id", referencedColumnName = "id", updatable = true, insertable = true)
    private Parent parent;

The @JsonBackReference also seems to avoid the circular structure when you create an openapi.json file.当您创建openapi.json文件时, @JsonBackReference似乎也避免了循环结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM