java - '无法添加或更新子行: a foreign key constraint fails' when trying to add a primary composite key in Hibernate

标签 java mysql hibernate composite-primary-key

我正在开展一个学校成绩册实现项目,其中有以下实体:学生、科目和成绩。每个年级都有一门科目、一名学生、日期和值。我正在尝试实现这种关系,我决定让一个年级有一个由科目 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
}

Grade(这里我通过在 Student_IdSubject_IdDate 上添加 @Id 标签来创建复合主键>,其中 Student_IdSubject_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();
    }
}

运行后出现以下异常:

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 DBMS。

最佳答案

首先尝试保留 Student 和Subject 对象。如果你不持久化这些对象,Hibernate 就无法在数据库中找到它们。

关于java - '无法添加或更新子行: a foreign key constraint fails' when trying to add a primary composite key in Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42249863/

相关文章:

java - 如何使用 Hibernate 仅获取一列的值

java - Hibernate 中 JTA、JPA 和普通 JDBC 的区别

java - 如何强制泛型类型参数成为接口(interface)?

java - 线程 "main"中出现异常,Picture.java 和 PictureTester.java 中的mirrorHorizo​​ntal 类?

java - 如何通过字符串从类的对象中获取值?

删除 php mysql 结果反斜杠

mysql - 初学者需要帮助编写按月、县和计划列出的支出 SQL 查询

java - 如何将 spring bean 注入(inject)到 hibernate envers RevisionListener 中

java - 家庭/远程接口(interface) EJB 3.1 的目的是什么

mysql - 将自己排除在友谊页面之外 - MySQL