CascadeTyp.ALL和显式包括所有CascadeTypes有什么区别?

时间:2019-07-15 07:07:01

标签: java jpa one-to-many cascade many-to-one

我是新来的休眠者,今天我发现在one_to_many模式下有关CascadeType的一些事情。

情况1:CascadeType.ALL 在这种情况下,一切正常。保存对象时,所有相关对象也将被保存(级联期望)。例如,当创建课程对象并分配了讲师对象时,保存课程对象意味着两者都被保存。

情况2:明确键入所有选项

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

在这种情况下,尽管提到了所有可能的选项,但都会引发异常并指出:

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

我想知道区别是什么。

这是在休眠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);
    }
}

1 个答案:

答案 0 :(得分:1)

始终记住,当您使用级联类型ALL时,它不仅包括所有显式的级联事件(持久,分离,删除..etc),而且还包括一些休眠的本机级联类型(Lock)。这个错误也说明了同样的情况。它强制休眠保存所有子对象,然后再保存父对象。

Cascade.ALL !={CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH}

不仅如此。...:)

请仔细阅读以下文章,您将会了解

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