2

如何使用 JPA 实现以下关系?

table person (
  id int,
  name text
)

table person_home (
    person_id int,
    home_id int,
    type char(1)       -- 'p' = primary, 's' = secondary
)

table home (
    id int,
    address text
)

一个人可以有很多家,一个家可以有很多人住在里面(即多对多关系)。此外,房屋可以是一个人的主要住所,但同时也是另一个人的次要住所。

我不确定如何对这种关系建模,即使数据库模式很清楚。

我曾考虑将映射表 person_home 拆分为 person_primary_home 和 person_secondary_home,但是如果可能的话,我更愿意保留架构。

4

2 回答 2

1

这个问题在这里被问到并得到了回答:
How to create a composition primary key which contains a @ManyToOne attribute as an @EmbeddedId in JPA?

你需要四个类:

  1. 人.java
  2. 主页.java
  3. 个人主页.java
  4. PersonH​​omePk.java

您创建的 Person.java 和 Home.java 文件与 PersonH​​ome.java 具有一对多的关系。他们将有 @Id 字段来识别主键。每个都将定义一个 @OneToMany 关系,其中至少有一个 mappedBy 属性映射到 PersonH​​ome 实体中它们各自的字段。即在 Person.java 你可以有类似的东西

@OneToMany(cascade = CascadeType.ALL, mappedBy = "Person")
private Collection<PersonHome> personHome;

PersonH​​ome.java 将有一个 @EmbeddedId 字段来标识作为其主键的 PersonH​​omePk 实例声明(也就是说,而不是 @Id 列,您将有一个 @EmbeddedId 注释表示连接主键的类的声明表 PersonH​​ome)。任何其他字段都被声明为普通列。PersonH​​ome.java 还将声明两个 ManyToOne 关系,每个关系与人和家庭有关。这些将使用@JoinColumn 注释(确保它们具有属性 insertable=false 和 updatable=false)。数据类型将是 Person 和 Home 类。IE

@EmbeddedId
protected PersonHomePk personHomePk;
@Column (name = "type")
private String type; 
@JoinColumn(name = "person_id", referencedColumnName = "person_id", insertable = false, updatable = false)
@ManyToOne(optional = false)
private Person person;

“Home”声明也需要相同的内容。

为什么你只使用一个字符来表示“类型”。我推荐一个 varchar,这样当你不在时维护它的人会更好地理解代码和数据库。“分离”更容易理解“d”。

于 2012-06-15T20:31:52.043 回答
0

我相信,如果除了 person_home 表上的关系之外,您还需要元数据,则需要使用三个具有两个一对多关系的对象才能访问所有数据。

您可以通过从 person 表到 home 表建立两个多对一关系,通过 primary_home_id 和 secondary_home_id 来消除这种需求——除非我在这里遗漏了一个要求并且一个人可以有多个主要或次要家.

于 2012-06-15T19:31:22.367 回答