首页 > 解决方案 > H2 错误:违反参照完整性约束 - 休眠一对一映射

问题描述

我有两个实体(Instructor,InstructorDetail),它们具有一对一的关系。

Instructor 实体的instructor_detail_id 具有指向InstructorDetail 的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!";

    }

任何帮助,将不胜感激!提前致谢。

标签: javahibernatejpaforeign-keysh2

解决方案


推荐阅读