Archit
Archit

Reputation: 113

Save child objects automatically after saving parent

I've already looked at - Save child objects automatically using JPA Hibernate

Hibernate: OneToMany save children by cascade

I have following tables -

I'm trying to do - save(instructorDetail) in my MainApp and expecting associated instructors and courses to be save automatically

Here are my classes -

@Entity @Table(name="instructor_detail") public class InstructorDetail { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) @Column(name="id") private int id; @Column(name="youtube_channel") private String youtubeChannel; @Column(name="hobby") private String hobby; @OneToOne(mappedBy = "instructorDetail", cascade= { CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH }) private Instructor instructor; //getters and setters } @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; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="instructor_detail_id") private InstructorDetail instructorDetail; @OneToMany(mappedBy="instructor", cascade = {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH}) private List<Course> courses; //...getters and setters //one more method to add courses public void addCourse(Course c) { if(courses == null) { courses = new ArrayList<>(); } courses.add(c); c.setInstructor(this); } } @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.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH}) @JoinColumn(name="instructor_id") private Instructor instructor; //getters and setters } //MainClass - public class OneToManyBiDirectionalDemo { public static void main(String[] args) { Course c1 = new Course("Multithreading"); Course c2 = new Course("WebDevelopment"); Instructor ins1 = new Instructor("John","Purcell","[email protected]"); InstructorDetail insDet1 = new InstructorDetail("com.john.purcell","teaching"); insDet1.setInstructor(ins1); ins1.setInstructorDetail(insDet1); ins1.addCourse(c1); ins1.addCourse(c2); SessionFactory factory = new Configuration(). configure("hibernate.cfg.xml"). addAnnotatedClass(Course.class). addAnnotatedClass(Instructor.class). addAnnotatedClass(InstructorDetail.class). buildSessionFactory(); Session session = factory.getCurrentSession(); session.beginTransaction(); session.save(insDet1); session.getTransaction().commit(); session.close(); factory.close(); } }

My expectation is - when save(instructorDetail) is called in MainClass, the instructor and courses should also be save automatically. However, executing the current only saves instructor detail and not instructor and courses. Only one insert is fired in log and there are not exceptions generated. I'm new to Hibernate, so my expectations or understanding may be off. Is this possible though?

Upvotes: 1

Views: 599

Answers (1)

Ken Chan
Ken Chan

Reputation: 90427

The JPA CascadeType that you configured (DETACH,MERGE,PERSIST,REFRESH) only has cascading effect when using with Session 's evict() , merge() , persist() , refresh(). (See this)

But you are using session.save() for saving the objects .That 's why it does not any the cascading effect. Change to either one of the following should solve the problem:

(1) Change all CascadeType to ALL.

(2) Use session.persist() to insert the record:

  session.persist(insDet1);

Upvotes: 1

Related Questions