CascadeTyp.ALL 和显式包含所有 CascadeType 之间有什么区别?

what is the difference between CascadeTyp.ALL and explicitly including all CascadeTypes?

我是 hibernate 的新手,今天我发现了一些关于 one_to_many 模式下的 CascadeType 的东西。

案例 1:CascadeType.ALL 在这种情况下,一切正常。当一个对象被保存时,所有相关的对象也会被保存(正如级联所期望的那样)。例如,当创建一个 Course 对象并为其分配一个 Instructor 对象时,保存 Course 对象意味着两者都被保存。

情况 2:显式键入所有选项

    @ManyToOne(cascade = {CascadeType.DETACH,
        CascadeType.MERGE,
        CascadeType.PERSIST,
        CascadeType.REFRESH,
        CascadeType.REMOVE})

在这种情况下,尽管提到了每个可能的选项,但抛出异常并显示:

TransientObjectException:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例

我想知道有什么不同。

这发生在 hibernate 5.4.3 上。

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

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

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

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

    //    @ManyToOne(cascade = CascadeType.ALL)
    @ManyToOne(cascade = {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH,
            CascadeType.REMOVE})
    @JoinColumn(name = "instructor_id")
    private Instructor instructor;

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

    public Course() {

    }

    public Instructor getInstructor() {
        return instructor;
    }

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

}


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

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

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

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

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

    @OneToMany(mappedBy = "instructor", cascade = CascadeType.ALL)
    private List<Course> courses;



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

    public Instructor() {
    }

    public List<Course> getCourses() {
        return courses;
    }

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

    public void add(Course tempCourse){
        if (courses==null){
            courses = new ArrayList<>();
        }
        courses.add(tempCourse);
        tempCourse.setInstructor(this);
    }
}

永远记住,当您使用级联类型 ALL 时,它不仅包括所有显式级联事件(持久化、分离、删除等),还包括一些休眠本机级联类型(锁定)。这个错误也讲述了同样的故事。它强制 hibernate 在保存父对象之前保存所有子对象。

一言以蔽之Cascade.ALL !={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH}

不止于此....:)

请看下面的文章,你就明白了

https://dzone.com/articles/beginner%E2%80%99s-guide-jpa-and