JPA Hibernate @ManyToOne 外键约束失败

JPA Hibernate @ManyToOne foreign key constraint fails

我正在编写一个基本示例来测试级联删除操作,但出现异常。这是我的实体

@Table(name = "project")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Project implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "project_name")
    private String projectName;

    @ManyToOne(cascade = CascadeType.REMOVE)
    private Student student;

    ...
} 

@Entity
@Table(name = "student")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;
 
    ...
}

我已经有一个学生数据和一个与之相关的项目,我的期望是当我删除学生数据时,该项目会自动删除。但是当我删除学生数据时,出现错误

Caused by: java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`document_control`.`project`, CONSTRAINT `FKjvi932wdxw4ux6m7u6abiy7qv` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`))

我正在使用 JPA 删除数据,这是我的控制器 class

@DeleteMapping("/students/{id}")
    public ResponseEntity<Void> deleteStudent(@PathVariable Long id) {
        log.debug("REST request to delete Student : {}", id);
        studentRepository.deleteById(id);
        return ResponseEntity
            .noContent()
            .headers(HeaderUtil.createEntityDeletionAlert(applicationName, false,
                ENTITY_NAME, id.toString()))
            .build();
    }

我是不是漏掉了什么?

问题在于从ProjectStudent的外键缺少选项:“on delete cascade”...这样的选项指示数据库删除那些Projects 取决于已删除的 Student ...如果未配置任何选项,您的数据库将抱怨“约束违规错误”,就像您所面临的那样 ...

看来您正在通过休眠创建数据库模型...将此类选项添加到约束中以遵循 this 示例...结果应该是这样的:

@Entity
@Table(name = "project")
public class Project {
    ...
    @ManyToOne
    @JoinColumn(
        name = "student_id", 
        nullable = false,
        foreignKey = @ForeignKey(
            name = "FK_STUDENT_ID",
            foreignKeyDefinition = "FOREIGN KEY (student_id) REFERENCES student(id) ON DELETE CASCADE"
    )
    private Student student;
    ...
}

注意:这只是一个简单的例子,你必须自己测试。

从父级到子级的级联 REMOVE 操作将需要父级到子级的关系(不只是相反,这似乎是您目前拥有的)。话虽如此,尝试创建双向关系如下:

@Entity
@Table(name = "student")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Student implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;
 
    @OneToMany(mappedBy = "student", cascade = CascadeType.REMOVE)
    private Set<Project> projects;
}

此外,考虑从 Project 中删除级联 REMOVE 操作,否则您可能会在删除 Project 时删除 Student