【发布时间】:2012-02-16 20:13:27
【问题描述】:
我有一个相当独特的情况,试图将单个表映射到 JPA 中的多个实体。我已阅读有关@Embeddable 和@ElementCollection 的信息,但我不确定如何在我的情况下使用它们(或者如果可以的话)。一个数据库表保存课程信息。表中可能有行,其中课程中的所有内容都相同,除了一些值,例如房间号和日期。例如:
TERM_CODE SUBJECT_CODE ROOM DAY INSTRUCTOR_ID
201220 EGRE 0101 TR 123
201220 EGRE 0103 W 124
有没有一种方法可以像上面那样从两行中提取数据,并将公共数据放在一个对象中,将不同的值放在不同对象的集合中?这是我希望如何定义类的示例:
@Entity
public class Course implements Serializable {
@Id
@Column(name = "TERM_CODE")
private Long termCode;
@Column(name = "SUBJECT_CODE")
private String subjectCode;
@Embedded
Collection<CourseSchedule> schedule;
public Long getTermCode() {
return termCode;
}
public void setTermCode(Long termCode) {
this.termCode = termCode;
}
public String getSubjectCode() {
return subjectCode;
}
public void setSubjectCode(String subjectCode) {
this.subjectCode = subjectCode;
}
}
课程安排:
@Embeddable
public class CourseSchedule {
private String room;
private String day;
public String getRoom() {
return room;
}
public void setRoom(String room) {
this.room = room;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getInstructorId() {
return instructorId;
}
public void setInstructorId(String instructorId) {
this.instructorId = instructorId;
}
}
我也很困惑,一旦我将 JPQL 映射到这种情况下,它们会是什么样子。
编辑:
如果我将@Id 添加到 TERM_CODE 列,则返回 Course 对象而不会出现 Hibernate 错误,但作为 Course 一部分的 CourseSchedule 集合为空。
编辑 2:
我尝试将 Course 和 CourseSchedule 视为两个单独的表(即使它们不是),但我似乎无法使用 @OneToMany 和 @ManyToOne 将它们连接起来。
@Entity
@IdClass(CourseId.class)
@Table(name = "course_table")
public class Course implements Serializable {
@OneToMany(mappedBy = "course")
private Collection<CourseSchedule> schedule;
@Id
@Column(name = "TERM_CODE")
private Long termCode;
@Id
@Column(name = "SUBJECT_CODE")
private Long subjectCode;
...
}
@Entity
@IdClass(CourseScheduleId.class)
@Table(name = "course_table")
public class CourseSchedule implements Serializable {
@ManyToOne
@JoinColumns({
@JoinColumn(name="TERM_CODE", referencedColumnName="TERM_CODE"),
@JoinColumn(name = "SUBJECT_CODE", referencedColumnName="SUBJECT_CODE")
})
private Course course;
@Column(name = "TERM_CODE")
private Long termCode;
@Column(name = "SUBJECT_CODE")
private Long subjectCode;
@Id
private String room;
@Id
private String day;
@Id
@Column(name = "INSTRUCTOR_ID")
private String instructorId;
...
}
(CourseId 和 CourseScheduleId 是用于复合 ID 的简单类。)上述映射返回以下错误:
org.hibernate.MappingException: Foreign key (FK82D03688F590EF27:course_table [TERM_CODE,SUBJECT_CODE])) must have same number of columns as the referenced primary key (course_table [ROOM,DAY,INSTRUCTOR_ID)
如果这有助于简化课程,我不需要 CourseSchedule 来引用课程。
有什么想法吗?我唯一的其他想法是将它们定义为完全独立的实体(未连接),然后使用 JPQL 以某种方式将它们映射在一起。
【问题讨论】:
-
我猜这是一个现有的数据库?所以你不能在 CourseSchedule 表中使用 TERM_CODE 的外键?我可能有充分的理由这样做,但您复制了相当多的数据只是为了存储 ROOM 和 DAY 信息。当你像这样映射它时,hibernate 会报告什么?
-
不幸的是我无法更改数据库,并且都在一个表中。我希望我能说服他们将其正常化,但这并没有发生。
-
如果我以当前形式运行它,我会收到错误“没有为实体指定标识符:课程”,这是我几乎应该预料到的。另一个问题是数据库表没有定义主键。