Hibernate 中的 OneToMany 单向映射。引用实体中的问题设置外键

OneToMany unidirectional mapping in Hibernate. Issue setting foreign key in referenced entity

假设有两个实体:ParentChild,具有 @OneToMany 映射从 ParentChild.

class Parent {
    @Column(name="id")
    private Long id;

    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "parent_id", referencedColumnName = "id")
    private List<Child> children;
}

class Child {
    @Column(name="id")
    private Long id;

    @Column(name="parent_id")
    private Long parentId;
}

如您所见,在我的例子中,Child table 将外键存储到 Parent的主键。但我不希望它作为我的 Child 实体中的 bi-directional 映射。

现在出现的问题是,我无法在 Child 个实例中设置 parent_id

我创建了这样的实例:

Parent parent = new Parent();
parent.setChildren(Lists.newArrayList(new Child(), new Child()));
parentDomainService.save(parent);

假设Parent端有级联。这种方法首先保存 Parent,然后保存 Child 实例。然后它在 child 实例上运行更新查询以更新 parent_id,正如我从 Hibernate show_sql 日志中看到的那样。但令人惊讶的是,更新查询后,我看到一些 childparent_idnull。这让我很惊讶。

所以,我去手动处理那个东西,并删除了级联。然后我这样保存实体:

Parent parent = new Parent();
parent.setChildren(Lists.newArrayList(new Child(), new Child()));
parent = parentDomainService.save(parent);

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

这个问题在我身上反弹,但有以下例外:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.somepkg.Child

我已经看到很多关于 SO 的问题,但我知道那里有很多问题,但几乎所有问题都在处理 bi-directional 映射,或 uni-directional 与 JoinTable 的映射.两者都不适合我的情况。

这里有灯吗?我别无选择。

P.S.: 我正在处理的实际场景需要保存大量数据。例如:50000 parent 条记录和 250000 Child 条记录。这就是为什么我不想要 bi-directional 映射。因为保存 Child 确实会在 back-end.

中创建一个带有连接 table 的查询

我最感兴趣的是解决方案,其中我不必在 Child table 上触发两次查询。正如我当前的应用程序中发生的那样,这会影响性能。

当您移除级联时,父元素不会保留引用的子元素并且在

parent = parentDomainService.save(parent);

父引用 "unsaved transient" 子实例,因此抛出异常。如果先保存父项然后添加子项:

Parent parent = new Parent();
parent = parentDomainService.save(parent);
parent.setChildren(Lists.newArrayList(new Child(), new Child()));

for (Child child: parent.getChildren()) {
    child.setParentId(parent.getId());
} 

childDomainService.save(parent.getChildren());

则不会抛出异常