'Cannot add or update a child row: a foreign key constraint fails' 尝试在 Hibernate 中添加主复合键时
'Cannot add or update a child row: a foreign key constraint fails' when trying to add a primary composite key in Hibernate
我正在从事学校成绩册实施项目,其中包含以下实体:学生、科目和成绩。每个年级都有一个科目、一名学生、日期和值。我正在尝试实现这种关系,我决定让一个年级有一个由主题 ID、学生 ID 和日期组成的复合主键,这是我的实体 类
学生:
@Entity
@Table(name="Students")
public class Student {
@Id @Column(name="Student_Id")
private int studentId;
@Column(name="First_Name")
private String firstName;
@Column(name="Last_Name")
private String lastName;
//getters and setters
}
主题:
@Entity
@Table(name="Subjects")
public class Subject {
@Id @Column(name="Subject_Id")
private int subjectId;
@Column(name="Subject_Name")
private String subjectName;
//getters and setters
}
等级(这里我通过在 Student_Id
、Subject_Id
和 Date
上添加 @Id
标记来创建复合主键,其中 Student_Id
和 Subject_Id
也是外键):
@Entity
@Table(name="Grades")
public class Grade implements Serializable{
@Id
@ManyToOne @JoinColumn(name="Student_Id", foreignKey=@ForeignKey(name="FK_Grades_Student"))
@Cascade(CascadeType.SAVE_UPDATE)
private Student student;
@Id
@ManyToOne @JoinColumn(name="Subject_Id", foreignKey=@ForeignKey(name="FK_Grades_Subject"))
@Cascade(CascadeType.SAVE_UPDATE)
private Subject subject;
@Column(name="Date")
@Id
private Date date;
@Column(name="Letter_Value") //A,B,C,D,F
private String letterValue;
//getters and setters
}
这是我 运行 来自 Main
的方式:
public class Main {
public static void main(String[] args) {
Subject subject = new Subject(); subject.setSubjectId(1); subject.setSubjectName("Biology");
Student student = new Student(); student.setStudentId(1); student.setFirstName("Jack"); student.setLastName("Smith");
Grade grade = new Grade(); grade.setStudent(student); grade.setSubject(subject); grade.setDate(new Date()); grade.setLetterValue("B");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(grade);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
在 运行ning 之后我得到以下异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails (`grades_book_db`.`grades`, CONSTRAINT `FK_Grades_Subject` FOREIGN KEY (`Subject_Id`) REFERENCES `subjects` (`Subject_Id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 18 more
如何解决这个异常,如何实现我上面提到的组合键?我正在使用 MySQL 数据库管理系统。
首先尝试保留 Student 和 Subject 对象。如果您不持久化它们,Hibernate 将无法在数据库中找到这些对象。
我正在从事学校成绩册实施项目,其中包含以下实体:学生、科目和成绩。每个年级都有一个科目、一名学生、日期和值。我正在尝试实现这种关系,我决定让一个年级有一个由主题 ID、学生 ID 和日期组成的复合主键,这是我的实体 类
学生:
@Entity
@Table(name="Students")
public class Student {
@Id @Column(name="Student_Id")
private int studentId;
@Column(name="First_Name")
private String firstName;
@Column(name="Last_Name")
private String lastName;
//getters and setters
}
主题:
@Entity
@Table(name="Subjects")
public class Subject {
@Id @Column(name="Subject_Id")
private int subjectId;
@Column(name="Subject_Name")
private String subjectName;
//getters and setters
}
等级(这里我通过在 Student_Id
、Subject_Id
和 Date
上添加 @Id
标记来创建复合主键,其中 Student_Id
和 Subject_Id
也是外键):
@Entity
@Table(name="Grades")
public class Grade implements Serializable{
@Id
@ManyToOne @JoinColumn(name="Student_Id", foreignKey=@ForeignKey(name="FK_Grades_Student"))
@Cascade(CascadeType.SAVE_UPDATE)
private Student student;
@Id
@ManyToOne @JoinColumn(name="Subject_Id", foreignKey=@ForeignKey(name="FK_Grades_Subject"))
@Cascade(CascadeType.SAVE_UPDATE)
private Subject subject;
@Column(name="Date")
@Id
private Date date;
@Column(name="Letter_Value") //A,B,C,D,F
private String letterValue;
//getters and setters
}
这是我 运行 来自 Main
的方式:
public class Main {
public static void main(String[] args) {
Subject subject = new Subject(); subject.setSubjectId(1); subject.setSubjectName("Biology");
Student student = new Student(); student.setStudentId(1); student.setFirstName("Jack"); student.setLastName("Smith");
Grade grade = new Grade(); grade.setStudent(student); grade.setSubject(subject); grade.setDate(new Date()); grade.setLetterValue("B");
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
session.save(grade);
session.getTransaction().commit();
session.close();
sessionFactory.close();
}
}
在 运行ning 之后我得到以下异常:
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
Cannot add or update a child row: a foreign key constraint fails (`grades_book_db`.`grades`, CONSTRAINT `FK_Grades_Subject` FOREIGN KEY (`Subject_Id`) REFERENCES `subjects` (`Subject_Id`))
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
at com.mysql.jdbc.Util.getInstance(Util.java:408)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3970)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3906)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2524)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2677)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2549)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1861)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2073)
at com.mysql.jdbc.PreparedStatement.executeUpdateInternal(PreparedStatement.java:2009)
at com.mysql.jdbc.PreparedStatement.executeLargeUpdate(PreparedStatement.java:5098)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1994)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
... 18 more
如何解决这个异常,如何实现我上面提到的组合键?我正在使用 MySQL 数据库管理系统。
首先尝试保留 Student 和 Subject 对象。如果您不持久化它们,Hibernate 将无法在数据库中找到这些对象。