// This will ALSO save the detail object // because of the CascadeType.ALL System.out.println("Saving instructor: "+instructor); session.save(instructor);
Look at the instructorDetail property in the Instructor class.
Use property name!
1 2 3 4 5
publicclassInstructor{ @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="instructor_detail_id")// link to the db private InstructorDetail instructorDetail; }
Use the info from the Instructor class @JoinColumn
// break teh bi-directional link // remove the associated object reference instructorDetail.getInstructor().setInstructorDetail(null);
// Delete the instructor detail and cascade delete the instructor System.out.println("Deleting " + instructorDetail); session.delete(instructorDetail);
@OneToMany(mappedBy="instructor") // refers to the "instructor" property in the "Course" class private List<Course> courses;
Note: Apply ALL the cascading types except REMOVE!
Uni-Directional
Use Case
We have Course Entity and Review Entity. But a review without a course is meaningless, so if the course is deleted, then the related reviews should apply cascading deletes.
Inversely, look at the student_id column in the course_student table.
Note: Do not apply cascading deletes!
Eager vs Lazy Loading
Eager Loading
It will retrieve everything and load all entites.
1 2 3
@OneToMany(fetch = FetchType.EAGER, mappedBy = "instructor")//refers the instructor property in the course.class private List<Course> courses;
Lazy Loading
It will retrieve on request.
1 2 3
@OneToMany(fetch = FetchType.LAZY, mappedBy = "instructor")//refers the instructor property in the course.class private List<Course> courses;
Use Cases
Master View
we use the lazy loading.
Detail View
we retrieve the entity and necessary dependent entities.
Default Fetch Types
@OneToOne - EAGER
@OneToMany - LAZY
@ManyToOne - EAGER
@ManyToMany - LAZY
Resolve LAZY Loading Issue
Problem
If we close the session before the accessing LAZY data, what will we get?
1 2
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/hb-03-one-to-many?useSSL=false&serverTimezone=UTC] Exception in thread "main" org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.luv2code.hibernate.demo.entity.Instructor.courses, could not initialize proxy - no Session
How can we access the LAZY data after the session is closed?
Solution1
1
System.out.println("luv2Code: The Courses: "+ instructor.getCourses());
Retrieve the LAZY data before the session is closed. And the LAZY data is stored in memory to access.
Solution2
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// get the instructor from db int theId = 1;
Query<Instructor> query = session.createQuery("select i from Instructor i " + "JOIN FETCH i.courses " + "where i.id =:theInstructorId", Instructor.class);
// set the parameter on query query.setParameter("theInstructorId", theId);
// execute the query and get instructor Instructor tempInstructor = query.getSingleResult();
Use FETCH JOIN to generate and execute HQL Query. Retrive the LAZY data.
Reference: Udemy, Spring & Hibernate for Beginners (including SpringBoot)