JPA 派生的复合键
Posted
技术标签:
【中文标题】JPA 派生的复合键【英文标题】:JPA derived composite key 【发布时间】:2014-09-04 19:36:04 【问题描述】:我正在学习 JPA 2.1。我使用 sql 设计了一个数据库,但无法使用 JPA 2.1 做同样的事情。我列出了 sql 脚本。
create table SchoolClass (classNo int, constraint schoolClassPK Primary Key (classNo));
create table Section (classNo int, sectionId varchar(4), constraint sectionPK Primary Key(classNo, sectionId), constraint sectionClassNoFK Foreign Key (classNo) References SchoolClass(classNo));
create table Student (classNo int, sectionId varchar(4), rollNo int, name varchar(30), constraint studentPK Primary Key (classNo, sectionId, rollNo), constraint studentClassNoFK Foreign Key (classNo, sectionId) References Section(classNo, sectionId));
我的问题是在实现学生课程。这是我尝试用 JPA 做的事情:
@Entity
public class Schoolclass implements Serializable
@Id
private int classNo;
//other members follow
// IdClass
public class SectionCK implements Serializable
private int classNo;
private String sectionId;
// hashCode(), equals(Object), other members follow
@Entity
@IdClass(SectionCK.class)
public class Section implements Serializable
@Id
private int sectionPK;
@Id
private String sectionId;
@Id
@ManyToOne(cascade = PERSIST, MERGE )
@JoinColumn(name="SchoolClass_ClassNo", referencedColumnName="classNo")
private SchoolClass classNo;
//other members follow
// IdClass
public class StudentCK implements Serializable
private int classNo;
private String sectionId;
private int rollNo;
// hashCode(), equals(Object), other members follow
@Entity
@IdClass(StudentCK.class)
public class Student implements Serializable
@Id
private int rollNo;
@Column(name="name")
private String name;
@Id
@ManyToOne(cascade = PERSIST, MERGE )
@JoinColumns(
@JoinColumn(name="Section_SectionId", referencedColumnName="sectionId"),
@JoinColumn(name="Section_ClassNo", referencedColumnName="classNo")
)
private Section sectionId;
//other members follow
但这无法生成上述数据库。需要进行哪些更改?
【问题讨论】:
我是否在您的 SQL 代码中遗漏了什么?对于表Section
,您无需定义classSection
列,而是在PK 中引用它。与表相同Student
:classSection
在哪里?在Student
中,您将classNo
从Section
引用为FK。这样的列只存在于SchoolClass
。
classNo
没问题。只有classSection
坚持
您能详细说明失败的原因吗? zbigniewTomczak 的答案似乎是正确的,所以如果它不起作用,请显示什么错误或它产生了什么。您在上面的示例中加入列似乎是错误的,因为 Section 表中没有“SchoolClass_ClassNo”字段 - 如果这是使用的外键字段,它应该是“classNo”。在 Student 映射中定义的 joincolumns 存在相同的问题 - 它们与学生表中所需的字段不匹配。
@zbigniewTomczak 感谢您指出 SQL 脚本的问题,我已纠正。
【参考方案1】:
无论如何,请尝试从以下代码开始,然后朝着所需的映射方向努力。请记住,@IdClass
中字段的名称、类型和数量必须与实体中标记为 @Id
的字段匹配。
public class SectionCK
private String sectionId;
private int schoolClass;
@Entity
@IdClass(SectionCK.class)
public class Section implements Serializable
@Id
private String sectionId;
@Id
@ManyToOne
@JoinColumn(name="classNo")
private SchoolClass schoolClass;
public class StudentCK implements Serializable
private int rollNo;
private SectionCK section;
@Entity
@IdClass(StudentCK.class)
public class Student implements Serializable
@Id
private int rollNo;
@Column(name="name")
private String name;
@Id
@ManyToOne
@JoinColumns(
@JoinColumn(name="sectionId", referencedColumnName="sectionId"),
@JoinColumn(name="classNo", referencedColumnName="classNo")
)
private Section section;
此代码生成以下表格:
Table: Student
COLUMN_NAME |TYPE_NAME
------------------------------
ROLLNO |INTEGER
NAME |VARCHAR
CLASSNO |INTEGER
SECTIONID |VARCHAR
Table: SchoolClass
COLUMN_NAME |TYPE_NAME
------------------------------
CLASSNO |INTEGER
Table: Section
COLUMN_NAME |TYPE_NAME
------------------------------
SECTIONID |VARCHAR
CLASSNO |INTEGER
【讨论】:
我的代码和你的代码也没有区别。这是我已经尝试过但不起作用的方法。 是的,有区别。 1. 请注意,我在StudentCK
中使用SectionCK
。 2. 您将有@JoinColumn
name
属性产生不正确的列名。我的没问题。 3. 您还混合了@Id
名称和@IdClass
字段名称(sectionPK
)之间的名称。
zbigniewTomczak 感谢您指出问题并给出解决方案。以上是关于JPA 派生的复合键的主要内容,如果未能解决你的问题,请参考以下文章