gpt4 book ai didi

java - Hibernate/JPA 如何修复从子类错误生成数据库表

转载 作者:行者123 更新时间:2023-11-30 07:55:27 24 4
gpt4 key购买 nike

我在通过 JPA 和 Hibernate 注释在数据库中生成表时遇到了一些困难。

执行以下代码时,它会生成具有以下 EER 图的表格。

Generated EER Diagram of Person, Student and Teacher

这不是我希望它生成表格的方式。首先表之间的关系是错误的,它们需要是 OneToOne 而不是 OneToMany。其次,我不希望电子邮件成为学生和老师的主键。

在 Student 中,ovNumber 应该是主键,在 Teacher 中,employeeNumber我已经尝试使用 @Id 注释来完成它,但这给了我以下错误:

org.hibernate.mapping.JoinedSubclass cannot be cast to org.hibernate.mapping.RootClass

当我尝试使用 @MappedSuperClass 时,即使使用 @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS),表 person 也不会生成。

现在我的问题,

如何使子类中的另一个变量成为相应表的主键,同时将父类(super class)主键保留为外键?

如何将表之间的关系固定为 OneToOne 关系而不是 OneToMany 关系?

这是它应该如何的 EER 图。

EER Diagram of Person, Student and Teacher the way it should be

下面是用于生成表格的模型类。

Person.java

@Entity
@Polymorphism(type=PolymorphismType.IMPLICIT)
@Inheritance(strategy=InheritanceType.JOINED)
public class Person implements Comparable<Person>, Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name="email", length=64, nullable=false)
private String email;

@Column(name="firstName", length=255)
private String firstName;

@Column(name="insertion", length=255)
private String insertion;

@Column(name="lastName", length=255)
private String lastName;

public Person() {}

/**
* constructor with only email.
*
* @param email
*/
public Person(String email) {
this.email = email;
}

/**
* @param email
* @param firstName
* @param insertion
* @param lastName
*/
public Person(String email, String firstName, String insertion, String lastName){
this.setEmail(email);
this.setFirstName(firstName);
this.setInsertion(insertion);
this.setLastName(lastName);
}

//getters and setters
public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getInsertion() {
return insertion;
}

public void setInsertion(String insertion) {
this.insertion = insertion;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

@Override
public int compareTo(Person o) {
return email.compareTo(o.getEmail());
}
}

Teacher.java

@Entity
@Table(name="teacher")
@PrimaryKeyJoinColumn(name="email", referencedColumnName="email")
public class Teacher extends Person {

private static final long serialVersionUID = 1L;

//this needs to be the pk of teacher table
//@Id
@Column(name="employeeNumber", length=6, nullable=false)
private int employeeNumber;

@Column(name="abbreviation", length=6)
private String abbreviation;

public Teacher(){}

/**
* @param employeeNumber
* @param email
* @param firstName
* @param insertion
* @param lastName
*/
public Teacher(int employeeNumber, String email, String firstName, String insertion, String lastName){
super(email, firstName, insertion, lastName);
this.employeeNumber = employeeNumber;
setAbbreviation();
}

public String getAbbreviation() {
return abbreviation;
}

public void setAbbreviation() {
this.abbreviation = getLastName().substring(0, 4).toUpperCase() + getFirstName().substring(0, 2).toUpperCase();
}

public void setAbbreviation(String abbreviation){
this.abbreviation = abbreviation;
}

public int getEmployeeNumber() {
return employeeNumber;
}

public void setEmployeeNumber(int employeeNumber) {
this.employeeNumber = employeeNumber;
}

@Override
public String toString() {
return "Teacher [abbreviation=" + abbreviation + ", employeeNumber=" + employeeNumber + "]";
}
}

Student.java

@Entity
@Table(name="student")
@PrimaryKeyJoinColumn(name="email", referencedColumnName="email")
public class Student extends Person {

private static final long serialVersionUID = 1L;

@Column(name="cohort")
private int cohort;

//FIXME this needs to be the pk of student table
//@Id
@Column(name="ovNumber", nullable=false)
private int studentOV;


public Student(){}

public Student(int studentOV, int cohort, String email, String firstName,
String insertion, String lastName) {
super(email, firstName, insertion, lastName);
this.studentOV = studentOV;
this.cohort = cohort;
}

public int getCohort() {
return cohort;
}

public void setCohort(int cohort) {
this.cohort = cohort;
}

public int getStudentOV() {
return studentOV;
}

public void setStudentOV(int studentOV) {
this.studentOV = studentOV;
}

@Override
public int compareTo(Person o) {
return getEmail().compareTo(o.getEmail());
}

@Override
public String toString() {
return "Student [firstName=" + getFirstName() + ", insertion=" + getInsertion() + ", lastName=" + getLastName() + ", email="
+ getEmail() + ", cohort=" + getCohort() + ", studentOV=" + getStudentOV() + "]";
}
}

最佳答案

您的目标是实现继承,其中 Person 是您的父类(super class)。 TeacherStudent 是它的子类。 JPA 中的继承不像是 sql 实现。我建议阅读 following answer我前一段时间写过。另请阅读 JavaEE 7 - Entity Inheritance Tutorial .

##EDIT##

这是针对您所要求的每个实体使用不同主键的解决方案,我仍然认为这是不寻常的设计(对于其他人,请参阅原始消息):

人:

@Entity
public class Person implements Serializable {
@Id
@Column
private String email;

@OneToOne(mappedBy = "person")
private Teacher teacher;

@OneToOne(mappedBy = "person")
private Student student;
//more fields
}

老师

@Entity
public class Teacher implements Serializable {
@Id
@Column
private Integer employeeNumber;

//constrained to have to be assigned to a Person
//remove constraints if not needed
@OneToOne(optional = false)
@JoinColumn(unique = true, nullable = false)
private Person person;

//more fields
}

学生

@Entity
public class Student implements Serializable {
@Id
@Column
private Integer ovNumber;

//constrained to have to be assigned to a Person
//remove constraints if not needed
@OneToOne(optional = false)
@JoinColumn(unique = true, nullable = false)
private Person person;

//more fields
}

##原始消息##

对于您的问题,我建议改造您的 jpa 实体。将 Person 声明为一个抽象实体,通过 Person 扩展 Teacher 和 Student。

示例代码:

人物

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "PERSON_TYPE")
public abstract class Person implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
private Integer id;

//add your needed fields
}

分别是老师和学生

@Entity
public class Teacher extends Person {
//no ID needed, it inherits the id of Person
}

关于java - Hibernate/JPA 如何修复从子类错误生成数据库表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43200593/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com