Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Hibernate – Why is lazy loading not working here?

I am learning Hibernate from an online course, and right now, I am learning Eager vs Lazy loading.

For the example I have three entities and a test program like so:

@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(fetch = FetchType.LAZY,
            mappedBy = "instructor",
            cascade = {
                    CascadeType.DETACH,
                    CascadeType.MERGE,
                    CascadeType.PERSIST,
                    CascadeType.REFRESH
            })
    private List<Course> courses;
    
    // constructors
    
    public void add(Course tempCourse) {
        if (courses == null) {
            courses = new ArrayList<>();
        }
        
        if (tempCourse != null) {
            courses.add(tempCourse);
            tempCourse.setInstructor(this);
        }
    }
    
    // getters and setters
    
    @Override
    public String toString() {
        return "Instructor{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", instructorDetail=" + instructorDetail +
                '}';
    }
    
}
@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;
    
    // constructors
    
    // getters and setters
    
    @Override
    public String toString() {
        return "InstructorDetail{" +
                "id=" + id +
                ", youtubeChannel='" + youtubeChannel + '\'' +
                ", hobby='" + hobby + '\'' +
                '}';
    }
    
}
@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(fetch = FetchType.LAZY,
            cascade = {
                    CascadeType.DETACH,
                    CascadeType.MERGE,
                    CascadeType.PERSIST,
                    CascadeType.REFRESH})
    @JoinColumn(name = "instructor_id")
    private Instructor instructor;
    
    // constructors
    
    // getters and setters
    
    @Override
    public String toString() {
        return "Course{" +
                "id=" + id +
                ", title='" + title + '\'' +
                '}';
    }
    
}

Main Program:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

package pt.hmsk.hibernate.demo;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import pt.hmsk.hibernate.demo.entity.Course;
import pt.hmsk.hibernate.demo.entity.Instructor;
import pt.hmsk.hibernate.demo.entity.InstructorDetail;

public class EagerLazyDemo {
    
    public static void main(String[] args) {
        try (SessionFactory factory = new Configuration()
                .configure("hibernate.cfg.xml")
                .addAnnotatedClass(Instructor.class)
                .addAnnotatedClass(InstructorDetail.class)
                .addAnnotatedClass(Course.class)
                .buildSessionFactory();
             Session session = factory.getCurrentSession()) {
            
            // start a transaction
            session.beginTransaction();
    
            // get instructor from db
            int theId = 1;
            Instructor tempInstructor = session.get(Instructor.class, theId);
    
            System.out.println("luv2code: Instructor: " + tempInstructor);
            
            // get courses for the instructor
            System.out.println("luv2code: Courses: " + tempInstructor.getCourses());
            
            // commit transaction
            session.getTransaction().commit();
            
            System.out.println("luv2code: Done!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}

Then, I put a breakpoint in the main program at the line:

System.out.println("luv2code: Instructor: " + tempInstructor);

Supposedly here, no call to the courses field was done yet so, it shouldn’t be in the tempInstructor obejct, but debugging the program shows that the course was loaded into the Instructor obejct anyways:
debugger

Why is this happening??

>Solution :

You are lazy loading the courses, but because you are referencing them via the line

System.out.println("luv2code: Courses: " + tempInstructor.getCourses());

they are loaded in.

Turn on logging of the queries by adding to your hibernate.cfg.xml

<property name="hibernate.show_sql">true</property>

And don’t get the courses from the Instructor, then you will see, that they were in fact lazy-loaded.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading