【问题标题】:How to model in JPA a "default selection" from a One-to-Many Relationship如何在 JPA 中从一对多关系中建模“默认选择”
【发布时间】:2017-01-03 13:56:53
【问题描述】:

我有一个数据模型,其中一个或多个Names 可能知道Person(例如一个女人结婚后改名的情况)。该模型区分了正在使用的单个Name

PersonName 之间的一般关系照常建模:Person 实体中的双向 @OneToMany 关系和 Name 实体类中对应的 @ManyToOne 关系。

要指定“活动或主要名称”,我认为我可以将其建模为从PersonName 的单向@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


【解决方案1】:

我的建议是只保留人与姓名的关系(mappedSideNames)并删除由 uniPrimaryName 属性映射的关系以识别名称是否是主要的,您可以为此创建一个命名查询,但您必须创建一种通过设置标志来区分主要名称的方法。

【讨论】:

  • 是的,正如问题中所讨论的,实现此目的的一种方法是通过在Name 实体中创建一个布尔属性来指定主名称。保持这个属性并不简单。主名称也将是一个经常访问的属性。必须执行单独的查询才能获得它或使用应用程序逻辑来查找它似乎不是最佳解决方案
猜你喜欢
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多