I am running into the following behaviour in hibernate which I can't explain and I was hoping that someone can provide an explanation of what is going on.
I have a bidirectional @OneToMany
association between Instructor
and Course
. Since they have a CascadeType.PERSIST
I am expecting that when I create a Course
object and associate it to Instructor
and vice versa and then call the .save()
method on the instructor both objects will be persisted in the database, although that results in only the Instructor
to be persisted without the courses.
If I call the persist()
method for ex: session.persist(instructor)
both instructor and the courses are persisted.
Here are my entities and my main method.
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);
}
}
Course
@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;
}
}
Main
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);
}
}
}