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();
}
我是不是漏掉了什么?
问题在于从Project
到Student
的外键缺少选项:“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
。
我正在编写一个基本示例来测试级联删除操作,但出现异常。这是我的实体
@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();
}
我是不是漏掉了什么?
问题在于从Project
到Student
的外键缺少选项:“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
。