如何仅保存子实体并在表中填充 parentId 对子实体使用保存操作

How to save only a child entity and populate the parentId in the table Using save operation on the child entity

提问人:Rajesh Java guy 提问时间:8/19/2023 最后编辑:TuroRajesh Java guy 更新时间:8/24/2023 访问量:54

问:

我想理解这个基本概念。我们如何保存子实体并在 Child 表中填充外键 ID。我有这种情况,父母可以有很多孩子。但是孩子只能有一个父母。

`

Entity
@Table(name = "Child")
@SuppressWarnings("serial")
public class Child implements java.io.Serializable {

@ManyToOne
@JoinColumn(name = "parent_id")
private Parent parent;


}

-------------------------

@Entity
@Table(name = "parent")
@SuppressWarnings("serial")
public class Parent {


@OneToMany(mappedBy = "parent", fetch=FetchType.LAZY, cascade = CascadeType.ALL)
private List<Child> children;

}



` 我正试图像下面这样拯救孩子。但它给了我例外

关系“子项”的“父项”列不存在

Child child = new Child();
child.setParent(parent);
child.setXYZ("XYZ");

childRepository.save(child);

我正在尝试保存子实体,并希望它自动保存parent_id列。 我还尝试在名为

private Long parentId;

并试图替换这条线

child.setParent(父)

跟 child.setParentId(parentId);

但没有任何效果

Spring JPA 多对一 Hibernate-Cascade

评论

0赞 Turo 8/19/2023
案例很重要!我认为是错别字private Parent Parent
0赞 Rajesh Java guy 8/19/2023
非常感谢您指出这一点。这只是我的问题中的错别字。在我的代码中,它是正确的情况。
0赞 Chris 8/23/2023
该错误不太有意义 - 也许会发布确切的异常和堆栈。忽略它的不一致,我认为这意味着您的 JPA 提供程序正在处理 OneToMany 上的 mappedBy,并且在 Child 实体中找不到“父”引用。为什么不清楚(它说的是“孩子”而不是“孩子”)。我会尝试直接删除该映射(OneToMany),看看您的子实体是否真的被处理并且可以持久化,或者是否有其他错误以某种方式被掩盖。双向 1:M 映射非常常见,因此问题将隐藏在您未显示的内容中

答:

1赞 hermit 8/19/2023 #1

您尝试在双向一对多关系中实现的内容。并且,在双向关系中,您应该设置 .the both side of the reference

  1. 将父实体中的子列表初始化为:private List<Child> children = new ArrayList<>();

  2. 在父项中添加一个实用程序方法,以确保保存引用的两端。

    public void addChildren(Children child) {
        children.add(child);
        child.setParent(this);
    }
    
  3. 创建父对象,引用子对象并保存。

    Parent parent = new Parent();
    parent.addChildren(new Child());
    parentRepository.save(parent);
    

好读:https://vladmihalcea.com/the-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate/

如果父项已经存在(假设 id = 1),并且您需要添加另一个子项,则可以执行以下操作:

Parent parent = parentRepository.findById(id);
parent.addChildren(new Child());
parentRepository.save(parent);

评论

1赞 Chris 8/23/2023
我建议不要说最后一点。如果 Parent 已存在,则应从上下文中找到该实例并向其添加子实例,而不是创建一个新实例。如果你创建一个新的实例,然后对它调用 save,你就会将这个空的 Parent 实例合并到上下文中 - 它将用空的 Parent 数据覆盖 entity/db 中的所有其他 Parent 数据。也许您打算在 Child 上调用 save - 只要 Child->parent 关系没有设置级联合并/持久化,这就会起作用。
0赞 hermit 8/24/2023
@Chris,谢谢你的指出。已更新代码。