如何配置(可选)OneToOne复合主键?

时间:2014-09-14 18:37:07

标签: java hibernate jpa

我正在使用Hibernate并且有两个表,STUDENTS和DORM_ROOMS,它们与复合键相关:

STUDENTS table:
CAMPUS(String)      Part of Composite Key
STUDENT_ID (int)    Part of Composite Key
NAME (String)
...

DORM_ROOMS table:
CAMPUS(String)      Part of Composite Key
STUDENT_ID (int)    Part of Composite Key
ROOM_NUMBER(int)
...

这种关系是一对一的,因为学生可以只与一个宿舍相关联,宿舍与一个学生相关(哇 - 私人房间!)。但是,并非所有学生都有宿舍。

我的初始代码(被剥离)看起来像:

FOR STUDENTS:
@Embeddable
public class StudentsPK implements Serializable {
@Column(name = "CAMPUS")
private String Campus;
@Column(name = "STUDENT_ID")
private String StudentID;
...
}


@Entity
@Table(name = "STUDENTS")
public class Students implements Serializable {
@EmbeddedId
private StudentsPK studentsPK;
...
}


FOR DORM_ROOMS:
@Embeddable
public class DormRoomsPK implements Serializable {
@Column(name = "CAMPUS")
private String Campus;
@Column(name = "STUDENT_ID")
private String StudentID;
...
}


@Entity
@Table(name = "DORM_ROOMS")
public class DormRooms implements Serializable {
@EmbeddedId
private DormRoomsPK dormRoomsPK;
...
}

假设已经定义并创建了数据库模式。特别是,CAMPUS + STUDENT_ID是STUDENTS的PK,而CAMPUS + STUDENT_ID是DORM_ROOMS的FK,用作该表中的PK。此时我可以成功地在STUDENTS中插入一行,在DORM_ROOMS中插入一行。即使学生没有宿舍,我也可以从学生那里找回任何学生。但是,我还没有“通知”Hibernate关于两个表之间的关系。这就是我感到困惑的地方。

我试图通过使用“JOIN”注释“关联”这两个表但我发现这会导致任何尝试获取没有宿舍空间的学生返回空结果集。我想这是因为如果“JOIN”表示表总是被视为已连接,那么加入一个没有宿舍的学生,而DORM_ROOMS表中没有匹配的行会导致结果集为空。

由于使用“JOIN”注释不起作用,如何修改我的代码来描述两个表之间的关系,但仍允许我提取没有匹配宿舍的学生?

谢谢。

2 个答案:

答案 0 :(得分:1)

听起来您正在寻找@OneToOne annotation,它还可以指定关系是否为optionalJBoss JPA 2.1 docs中描述了一些示例,其中之一就是其中之一。

Example 3: One-to-one association from an embeddable class to another entity.

@Entity
public class Employee {
  @Id int id;
  @Embedded LocationDetails location;
  ...
}

@Embeddable
public class LocationDetails {
  int officeNumber;
  @OneToOne ParkingSpot parkingSpot;
  ...
}

@Entity
public class ParkingSpot {
  @Id int id;
  String garage;
  @OneToOne(mappedBy="location.parkingSpot") Employee assignedTo;
}

答案 1 :(得分:1)

发现问题了!我发现在与复合键的@OneToOne关系中,使用单独的FK类来管理两个实体中的复合键会导致错误。问题显示在我的原始帖子中,我定义并使用StudentsPK和DormRoomsPK!一旦我改为使用单个“PK”类而不是这两个,我的问题就被消除了。 (这似乎不是一个记录良好的要求!)