Reputation: 499
I am working on a basic example to test cascade delete operation but I am getting exception. Here is my entities
@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;
...
}
and
@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;
...
}
I already have one student data and one project related to it, and my expectation is when I delete student data, that project will automatically be deleted. But when I delete student data, I got an error
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`))
I'm using JPA to delete the data, and here is my controller 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();
}
Am I missing something here?
Upvotes: 1
Views: 1841
Reputation: 3424
The problem resides in that the foreign key from Project
to Student
is missing the option: "on delete cascade" ... such option instructs the database to remove those Projects
that depend on the deleted Student
... if no option is configured, your database will complain with "Constraint violation errors", as the one that you're facing ...
It seems that you're creating your database model through hibernate ... to add such option to the constraint to can follow this example ... The result should be something like 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;
...
}
NOTE: this is just a quick example, you'll have to test it yourself.
Upvotes: 2
Reputation: 17460
Cascading REMOVE operations from the parent to the child will require a relation from the parent to the child (not just the opposite, which seems to be what you currently have). Having said that, try creating a bi-directional relationship as follows:
@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;
}
Additionally, consider removing the cascading REMOVE operations from Project
otherwise you might end up deleting a Student
upon deletion of a Project
.
Upvotes: 1