【发布时间】:2017-01-03 13:56:53
【问题描述】:
我有一个数据模型,其中一个或多个Names 可能知道Person(例如一个女人结婚后改名的情况)。该模型区分了正在使用的单个Name。
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 需要单独的数据库查询。
在我为这个设计投入时间之前,我想问问有没有人尝试过这个。我担心对象模型使用的实体对象会同时以单向和双向关系存在。
【问题讨论】:
-
我使用了你的第一个想法。它的主要问题是循环依赖:你不能删除一个人,因为它被它的名字引用,你不能删除一个名字,因为它被一个人引用。但是,如果您确保以正确的顺序执行操作并刷新,或者如果您使用延迟约束,它可以正常工作。
标签: java jpa database-design one-to-many one-to-one