gpt4 book ai didi

java - OneToMany 子实体在 save() 上未持久化

转载 作者:行者123 更新时间:2023-11-30 05:26:23 24 4
gpt4 key购买 nike

我在 hibernate 中遇到了以下行为,我无法解释,我希望有人能够解释正在发生的事情。

我在 InstructorCourse 之间建立了双向 @OneToMany 关联。由于他们有一个 CascadeType.PERSIST ,我希望当我创建一个 Course 对象并将其关联到 Instructor 时,反之亦然,然后调用讲师的 .save() 方法这两个对象都将保留在数据库中,尽管这会导致仅保留 Instructor 而无需保留类(class)。

如果我调用 persist() 方法,例如:session.persist(instructor),讲师和类(class)都会被保留。

这是我的实体和主要方法。

导师:

@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);
}
}

类(class)

@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 文档:

The @OneToMany association is by definition a parent association, even if it’s a unidirectional or a bidirectional one. Only the parent side of an association makes sense to cascade its entity state transitions to children.

更新:

根据this似乎调用 save() 而不是使用 JPA EntityManager.persist() 它还需要 Hibernate 特定的级联类型 SAVE_UPDATE。 (这与 JPA @OneToMany 定义不兼容)

关于java - OneToMany 子实体在 save() 上未持久化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58494645/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com