假设有两个实体:主实体和从属实体。
它们在数据库中的定义通常类似于dependants.master_id -> masters.id
,即从属实体持有对主实体的引用。
在JPA one2one双向关联中,这种情况通常如下所示:
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);
有没有通用的解决方法?我的意思是我不想从依赖方那里支持协会。
答案 0 :(得分:2)
一种解决方法可能是使用@PrePersist
。对于这两个实体,您可以实现以下方法:
大师
@PrePersist
private void prePersist() {
if(null == getDependant().getMaster()) {
getDependant().setMaster(this);
}
}
依赖
@PrePersist
private void prePersist() {
if(null == getMaster().getDependant()) {
getMaster().setDependant(this);
}
}
或者只是省略空检查。
答案 1 :(得分:1)
您有多个选择,但是所有选择都取决于在拥有方面正确设置关系,在您的情况下为Dependant
。最佳选择取决于您的需求和使用方式。例如,另一个答案讨论了定义@PrePersist
方法的问题,如果Master
和Dependent
之间的关联是在仅当首次保留母版时才建立的,则该方法很干净。
鉴于您正在使用字段级访问,您还可以考虑让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
,则可能很容易却意外地失败。如果您尝试替换Master
的{{1}}而没有显式删除原始的Dependant
,它也可能会失败。还有其他破解方法。
由于以非常简单的方式来管理关系需要细心和注重细节,因此我建议您硬着头皮,在任何地方手动进行,如果确实需要更多的东西而不是在坚持时创建关系新的Master
并遍历现有关系。