【问题标题】:How to properly manage associated JPA entities with OneToOne BiDirectional relation?如何正确管理具有 OneToOne BiDirectional 关系的关联 JPA 实体?
【发布时间】:2019-07-26 01:15:43
【问题描述】:

假设给定了 2 个实体:主实体和从属实体。

它们在 DB 中通常定义为 dependants.master_id -> masters.id,即依赖实体持有对主实体的引用。

在这种情况下,JPA one2one BiDirectional 关联通常如下所示:

class Master {
    @OneToOne(mappedBy="master")
    Dependant dependant
}
class Dependant {
    @OneToOne
    @JoinColumn("master_id")
    Master master
}

这种方法导致需要处理关系的双方,例如:

Master master = new Master();
Dependant dependant = new Dependant();
dependant.setMaster(master);
master.setDependant(dependant);
repository.save(master);

而不是更直观和更接近业务逻辑的一种:

Master master = new Master();
Dependant dependant = new Dependant();
master.setDependant(dependant);
repository.save(master);

是否有任何常见的解决方法?我的意思是我不想从依赖方支持关联。

【问题讨论】:

标签: java jpa entity-relationship


【解决方案1】:

一种解决方法可能是使用@PrePersist。对于这两个实体,您可以实现如下方法:

大师

@PrePersist
private void prePersist() {
    if(null == getDependant().getMaster()) {
        getDependant().setMaster(this);
    }
}

依赖

@PrePersist
private void prePersist() {
    if(null == getMaster().getDependant()) {
        getMaster().setDependant(this);
    }
}

或者也许只是省略空检查。

【讨论】:

  • 难道@PrePersist钩子只与实体对象的“persist”生命周期事件一起调用吗?这将服务于 OP 的特定示例案例,但不适用于他们可能经常遇到的各种其他案例。
  • @JohnBollinger 你可能是对的。取决于OP需要什么。也可以实现 getter/setter,这样这些东西就已经被处理了。
  • 是的,我正在考虑类似的事情。
【解决方案2】:

您有多种选择,但都取决于在拥有方正确设置关系,在您的情况下是Dependant。您的最佳选择取决于您的需求和使用模式。例如,另一个答案讨论了定义一个@PrePersist 方法,如果MasterDependent 之间的关联在且仅当master 首次被持久化时建立,则该方法可能非常干净。

鉴于您使用的是字段级访问权限,您还可以考虑让Master.setDependant() 为您完成这项工作:

class Master {
    // ...

    @OneToOne(mappedBy="master")
    private Dependant dependant;

    public void setDependant(Dependant dep) {
        if (dep != null) {
            dep.setMaster(this);
        } else if (dependant != null) {
            // leaves a dangling dependant ...
            dependant.setMaster(null);
        }
        dependant = dep;
    }

    // ...
}

这将确保当您将Dependant 分配给Master 时,会在Dependant 端自动建立互惠关系。然后,您需要确保将持久性操作指定为正确地从 Master 级联到 Dependant

但是请注意,这不是灵丹妙药。如果您将分离或删除的Dependant 分配给Master,它很容易但令人惊讶地失败。如果您尝试替换MasterDependant 而不明确删除原始的(如果有的话),它也可能会失败。还有其他方法可以打破它。

由于以非常简单的方式管理关系需要谨慎和关注细节,我建议你硬着头皮在任何地方手动进行一个新的Master 并遍历现有的关系。

【讨论】:

    猜你喜欢
    • 2021-05-22
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多