簡體   English   中英

OneToMany 子實體未保存在 save() 上

[英]OneToMany child entities not persisted on save()

我在 hibernate 中遇到了以下行為,我無法解釋,我希望有人可以解釋發生了什么。

我在InstructorCourse之間有一個雙向@OneToMany關聯。 因為他們有一個CascadeType.PERSIST我希望當我創建一個Course object 並將其與Instructor相關聯時,反之亦然,然后在講師上調用.save()方法,這兩個對象都將保留在數據庫中,盡管這會導致只有Instructor在沒有課程的情況下被堅持。

如果我為 ex 調用persist()方法: session.persist(instructor)講師和課程都將被保留。

這是我的實體和我的主要方法。

講師:

@Entity
@Table(name = "instructor")
public class Instructor {

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

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "instructor_detail_id")
    private InstructorDetail instructorDetail;

    @OneToMany(mappedBy = "instructor", cascade = {CascadeType.DETACH,
    CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
    private List<Course> courses = new ArrayList<>();

    public Instructor() {
    }

    public Instructor(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    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 List<Course> getCourses() {
        return courses;
    }

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }

    @Override
    public String toString() {
        return "Instructor{" +
            "id=" + id +
            ", firstName='" + firstName + '\'' +
            ", lastName='" + lastName + '\'' +
            ", email='" + email + '\'' +
            ", instructorDetail=" + instructorDetail +
            ", courses=" + courses +
            '}';
    }

    public void addCourse(Course course) {
        courses.add(course);
        course.setInstructor(this);
    }
}

課程

@Entity
@Table(name = "course")
public class Course {

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

    @Column(name = "title")
    private String title;

    @ManyToOne(cascade = {CascadeType.DETACH, CascadeType.MERGE,
        CascadeType.PERSIST, CascadeType.REFRESH}, fetch = FetchType.LAZY)
    @JoinColumn(name = "instructor_id")
    private Instructor instructor;

    public Course(String title) {
        this.title = title;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Instructor getInstructor() {
        return instructor;
    }

    public void setInstructor(Instructor instructor) {
        this.instructor = instructor;
    }
}

主要的

public class Test {

    public static void main(String[] args) {

        //create session factory
        SessionFactory sessionFactory = new Configuration()
            .configure("com/ysoft/config/hibernate.cfg.xml")
            .addAnnotatedClass(Instructor.class)
            .addAnnotatedClass(InstructorDetail.class)
            .addAnnotatedClass(Course.class)
            .buildSessionFactory();

        //create session
        Session session = sessionFactory.getCurrentSession();

        try (sessionFactory) {
            session.beginTransaction();

            Instructor instructor = new Instructor("John", "Doe", "John.Doe@email.com");
            InstructorDetail instructorDetail = new InstructorDetail("http://www.something.com", "Coding");

            Course mathCourse = new Course("Math");
            Course englishCourse = new Course("English");
            Course sportsCourse = new Course("Sports");

            instructor.addCourse(mathCourse);
            instructor.addCourse(englishCourse);
            instructor.addCourse(sportsCourse);

            instructor.setInstructorDetail(instructorDetail);

            session.save(instructor);

            session.getTransaction().commit();

            System.out.println("Persisted" + instructor);
        }
    }
}

如果我將@OneToMany級聯數組更改為CascadeType.ALL ,那么它可以工作 - 但我不知道為什么,因為相關類型已經存在。

子端不應指定級聯-引用最新的 Hibernate 文檔:

@OneToMany關聯根據定義是父關聯,即使它是單向或雙向關聯。 只有關聯的父方才有意義將其實體 state 轉換級聯到子級。

更新:

據此,它似乎調用save()而不是使用 JPA EntityManager.persist()它還需要特定於 Hibernate 的級聯類型SAVE_UPDATE (這與 JPA @OneToMany定義不兼容)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM