我有一个数据模型,其中Person
可能被一个或多个Name
所知(例如,她的名字结婚后)。该型号区分正在使用的单个Name
。如何在JPA中建立“一对多”关系中的“默认选择”
Person
和Name
之间的一般关系被建模为通常:在Person
实体的双向@OneToMany关系和在Name
实体类相应@ManyToOne关系。
要指定“主动或主要名称”,我认为我可以将此模型设置为从Person
到Name
的单向@OneToOne关系。在实体类的映射是这样的:
public class Person {
@Id @GeneratedValue(strategy = GenerationType.Identity)
private Long pers_id;
@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "name_id", nullable = false)
private Name uniPrimaryName;
:
:
@OneToMany(mappedBy = "owningSidePerson", fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private List<Name> mappedSideNames;
:
:
}
而且Name
实体类:
public class Name
@Id @GeneratedValue(strategy = GenerationType.Identity)
private Long name_id;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinTable (name = "XREF_NAMES_PERSON",
joinColumns = @JoinColumn(name = "name_id", nullable = false),
inverseJoinColumns = @JoinColumn(name = "pers_id", nullable = false))
private Person owningSidePerson;
:
:
}
这种模式的优点是,它让我访问主Name
作为一个简单的属性访问从Person
。它也应该更容易维护。不足之处在于序列化具有循环引用的实体Person
,但是无论是否存在单向关系都存在此问题。
另一种模式是将active
布尔型属性添加到Name
实体,并用它来指示关系中哪个实体是活动实体。缺点是保持属性不那么简单,并且获得活动的Name
将需要单独的数据库查询。
在我投入这个设计的时间之前,我想问问以前有没有人试过这个。我担心使用实体对象的对象模型会同时出现在单向和双向关系中。
我已经使用了你的第一个想法。它的主要问题是循环依赖:你不能删除一个人,因为它被它的名字引用,你不能删除一个名字,因为它是被一个人引用的。但是,如果您确保按照正确顺序执行操作并刷新,或者如果使用延迟约束,则可以正常工作。 –