Java 为单表继承模型自动生成person_id和student_id
我有两个实体Java 为单表继承模型自动生成person_id和student_id,java,jpa,persistence,eclipselink,auto-generate,Java,Jpa,Persistence,Eclipselink,Auto Generate,我有两个实体person和Student,Student实体扩展person并有自己的标识符studentNumber。创建新学生时,我希望自动生成两个标识号 以下代码段失败:person_id为NULL @RooEntity(identifierColumn = "personID", inheritanceType = "SINGLE_TABLE") @DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorTy
person
和Student
,Student实体扩展person并有自己的标识符studentNumber
。创建新学生时,我希望自动生成两个标识号
以下代码段失败:person_id为NULL
@RooEntity(identifierColumn = "personID", inheritanceType = "SINGLE_TABLE")
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING, length = 20)
@DiscriminatorValue("P")
public class Person {
}
学生实体
@RooEntity
@DiscriminatorValue("S")
public class Student extends Person {
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "studentNumber")
private long studentNumber;
}
在这里,我创建了一个新学生,生成了学生编号,但personid没有
private Student student;
/**
* @method Create a new student using our persistence model---Not Null variables
*/
public void CreateNewStudent(String firstName, String lastName, String telephone, Date birthday, GenderType gender){
student = new Student();
//set our variables and persist
student.setFirstName(firstName);
student.setLastName(lastName);
student.setTelephone(telephone);
student.setBirthDay(birthday);
student.setGender(gender);
student.persist();
}
}
创建学生时,我有没有办法同时创建studentNumber和personID?根据您的后续评论,您需要的是为
人员
提供主键标识符,为学生
提供唯一标识符。请注意,在当前设置中,只能自动生成一个键(许多DBMS只允许自动递增每个表的一列)。因此,我建议您首先为Person
定义主键列:
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorValue("P")
public class Person {
@Basic
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="personId")
private Long id;
}
请注意,在数据库中,您希望personId列作为自动增量。然后为学生编号定义单独的生成值注释。下面我展示的示例使用表生成器,但您可以做任何您想做的事情:
@Entity
@DiscriminatorValue("S")
public class Student extends Person {
@Basic
@TableGenerator(name="ID_GEN", table="identifier_table", pkColumnName="seq_name",
valueColumnName="seq_count", pkColumnValue="student_seq")
@GeneratedValue(strategy = GenerationType.TABLE, generator = "ID_GEN")
@Column(name = "studentNumber")
private Long studentNumber;
}
以下是您需要支持学生序列号生成的表的DDL,给出了上述示例:
create table identifier_table (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
seq_name VARCHAR(255) NOT NULL,
seq_count INT NOT NULL DEFAULT 0
);
首先,您将使用以下内容填充它:
insert into identifier_table (seq_name, seq_count) VALUES ('student_seq', 0);
当然,更简单的解决方案是将您的学生标识符声明为字符串,然后您可以只执行以下更简单的设置:
public class Student extends Person {
@Basic
@NotNull
@Column(name = "studentId")
private String studentIdentifier;
}
在保存每个记录之前,使用UUID类设置学生ID:
aStudent.setStudentIdentifier(UUID.randomUUID().toString());
希望这能有所帮助。我想你目前只能有一个GenerateValue。如果您想要两个,您需要不使用继承,即Person对StudentInfo有1-1,或者您可以在事件或应用程序中分配另一个id。EclipseLink会话上有一个API,用于获取新生成的id。我质疑这种设计。使用单表继承时,为什么在父表和派生表上都有主键?请显示您的模式。学生编号并不是用来标识特定记录的,它是一个表示学生标识的数字,person id应该是唯一有意义的主键。好的,请参阅下面我的答案,了解解决问题的一种方法。对于使用UUID.randUUID()创建学生标识的更简单解决方案,这真的很独特吗?有没有一种方法可以从一个随机数(例如10000)开始,然后对于每个添加到person表中的新学员,递增1?您可以在Oracle javadoc页面上阅读更多关于UUID的信息-。但我只想说,它非常独特。最后一件事,如果我将createNewStudent()方法更改为创建一个学生实体,而不是创建一个人,那么我的数据库是否应该使用您提到的对学生实体的更改生成一个个人id?是的,只要您在数据库中将
personId
列定义为自动递增,它就会自动生成。最后一件事我忘了提。不要将studentId数据库字段设置为非空,因为从概念上讲,您将在表中存储可能不是students的其他记录。在这种情况下,您不需要设置studentId列。请在EclipseLink会话上发布一个指向API的链接,生成ID。