#java #hibernate #jpa #foreign-keys #h2
Вопрос:
У меня есть две сущности (Инструктор, InstructorDetail), которые имеют отношение один к одному.
instructor_detail_id сущности Instructor имеет внешний ключ к столбцу идентификатора InstructorDetail. Итак, согласно моему требованию, когда Инструктор удаляется, соответствующий инструктор также должен быть удален, но не наоборот. Теперь, когда я пытаюсь удалить instructorDetail, он выдает ошибку ограничения целостности ссылок.
Примечание: Я использую H2 db.
Ниже приведены фрагменты кода.
Инструктор —
import javax.persistence.*;
@Table(name="instructor")
@Entity
public class Instructor implements IdentityMarker<Integer>{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="instructor_id")
private int id;
@Column(name="name")
private String name;
@Column(name="email")
private String email;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "instructor_detail_id")//, referencedColumnName = "id")
private InstructorDetail instructorDetail;
public Instructor(){
}
public Instructor(String name, String email) {
this.name = name;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public InstructorDetail getInstructorDetail() {
return instructorDetail;
}
public void setInstructorDetail(InstructorDetail instructorDetail) {
this.instructorDetail = instructorDetail;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
@Override
public String toString() {
return "Instructor{"
"id=" id
", name='" name '''
", email='" email '''
", instructorDetail=" instructorDetail
'}';
}
}
ИнструкторДетайл —
import javax.persistence.*;
@Table(name="instructor_detail")
@Entity
public class InstructorDetail implements IdentityMarker<Integer>{
@Id
@Column(name="id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name="youtube_link")
private String youtubeLink;
@Column(name="hobby")
private String hobby;
@OneToOne(cascade = {
CascadeType.DETACH,
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.REFRESH
},
mappedBy = "instructorDetail")
// this bi-directional relationship enables us to get the instructor when an instructionDetail is loaded.
private Instructor instructor;
public InstructorDetail(){
}
public InstructorDetail(String youtubeLink, String hobby){
this.youtubeLink = youtubeLink;
this.hobby = hobby;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getYoutubeLink() {
return youtubeLink;
}
public void setYoutubeLink(String youtubeLink) {
this.youtubeLink = youtubeLink;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Instructor getInstructor() {
return instructor;
}
public void setInstructor(Instructor instructor) {
this.instructor = instructor;
}
public Integer getReference() {
return id;
}
public void setReference(Integer id){ this.id = id;}
@Override
public String toString() {
return "InstructorDetail{"
"id=" id
", youtubeLink='" youtubeLink '''
", hobby='" hobby '''
'}';
}
@PreRemove
private void preRemove() {
System.out.println("pre remove call");
instructor.setInstructorDetail(null);
}
}
Ниже приведен клиентский код
private static void deleteInstructorDetail(){
InstructorDetailDao instructorDetailDao = new InstructorDetailDaoImpl();
InstructorDetail instructorDetail = instructorDetailDao.getInstructorDetail(2);
Instructor instructor = instructorDetail.getInstructor();
System.out.println("Instructor: " instructor);
boolean b = instructorDetailDao.deleteInstructorDetail(instructorDetail);
assert b == true: "InstructorDetail is not deleted!";
System.out.println("Trying to load Instructor.. It should be deleted!");
InstructorDao instructorDao = new InstructorDaoImpl();
instructor = instructorDao.getInstructor(instructor.getId());
assert instructor != null: "Instructor also got deleted!";
}
Любая помощь будет признательна! Заранее спасибо.
Комментарии:
1. Использование CascadeType.REMOVE в классе InstructorDetail для атрибута инструктора должно исправить это.
2. На самом деле я не собираюсь удалять инструктора при удалении объекта instructorDetail.