tb_child 中的外键为空,具有双向一对多关系
Foreign-key in tb_child is null with bidirectional one-to-many relationship
我正在创建我的第一个 Spring 引导应用程序,它具有 Java 持久性 API 以写入和读取 postgres 数据库。我浏览了许多教程和帖子以找出我的确切问题,看起来我目前与两个实体(Parent
和 Child
)有双向一对多关系,但外国- 当我写入数据库时,child
列的键总是 null
。
父实体:
@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;
}
子实体:
@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;
}
父服务:
...
@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
}
...
调用 create
方法后,我在 tb_parent
中有一个 parent
行,其中生成了一个 id
和一个或多个 child
行tb_child
具有生成的 id
和 parent_id
列的 null
值。
尽管我能找到很多描述类似问题的帖子,但我还没有找到适合我的解决方案。
更新#1:
一个常见的建议是在所有 child
元素中手动设置 parent
对象。但是,由于循环结构,这会导致 Whosebug 异常。
public void setChildren(Set<Child> children) {
children.forEach(child -> child.setParent(this));
this.children = children;
}
此外,感觉有点不对劲,因为几乎所有内容都由 JPA 注释自动管理,然后您必须手动同步数据。
感谢 Georgy Lvov 我能够找到最有效的解决方案。我必须执行以下步骤:
- 按照Georgy Lvov的建议删除
@Data
注释(非常感谢!)这基本上避免了生成的getter和setter 所有属性的方法以及导致 Whosebug 异常的 Lombok 方法 equals()、hashCode() 和 toString()。
- 用
@JsonManagedReference
注解在Parent
class中注解Set<Child> children;
变量。见下文:
@JsonManagedReference
@Schema(description = "child-list of the application")
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private Set<Child> children;
- 用
@JsonBackReference
注释在Child
class中注释private Parent parent;
。见下文:
@JsonBackReference
@ManyToOne(targetEntity = Parent.class, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", referencedColumnName = "id", updatable = true, insertable = true)
private Parent parent;
当您创建 openapi.json
文件时,@JsonBackReference
似乎也避免了循环结构。
我正在创建我的第一个 Spring 引导应用程序,它具有 Java 持久性 API 以写入和读取 postgres 数据库。我浏览了许多教程和帖子以找出我的确切问题,看起来我目前与两个实体(Parent
和 Child
)有双向一对多关系,但外国- 当我写入数据库时,child
列的键总是 null
。
父实体:
@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;
}
子实体:
@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;
}
父服务:
...
@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
}
...
调用 create
方法后,我在 tb_parent
中有一个 parent
行,其中生成了一个 id
和一个或多个 child
行tb_child
具有生成的 id
和 parent_id
列的 null
值。
尽管我能找到很多描述类似问题的帖子,但我还没有找到适合我的解决方案。
更新#1:
一个常见的建议是在所有 child
元素中手动设置 parent
对象。但是,由于循环结构,这会导致 Whosebug 异常。
public void setChildren(Set<Child> children) {
children.forEach(child -> child.setParent(this));
this.children = children;
}
此外,感觉有点不对劲,因为几乎所有内容都由 JPA 注释自动管理,然后您必须手动同步数据。
感谢 Georgy Lvov 我能够找到最有效的解决方案。我必须执行以下步骤:
- 按照Georgy Lvov的建议删除
@Data
注释(非常感谢!)这基本上避免了生成的getter和setter 所有属性的方法以及导致 Whosebug 异常的 Lombok 方法 equals()、hashCode() 和 toString()。 - 用
@JsonManagedReference
注解在Parent
class中注解Set<Child> children;
变量。见下文:
@JsonManagedReference
@Schema(description = "child-list of the application")
@OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval = true)
private Set<Child> children;
- 用
@JsonBackReference
注释在Child
class中注释private Parent parent;
。见下文:
@JsonBackReference
@ManyToOne(targetEntity = Parent.class, fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id", referencedColumnName = "id", updatable = true, insertable = true)
private Parent parent;
当您创建 openapi.json
文件时,@JsonBackReference
似乎也避免了循环结构。