我正在通過在線課程學習 Hibernate,而現在,我正在學習 Eager vs Lazy loading。
例如,我有三個物體和一個測驗程式,如下所示:
@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 '\''
'}';
}
}
主程式:
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();
}
}
}
然后,我在主程式的行中放置了一個斷點:
System.out.println("luv2code: Instructor: " tempInstructor);
假設在這里,還沒有呼叫 course 欄位,所以它不應該在 tempInstructor 物件中,但除錯程式顯示課程已加載到 Instructor 物件中:

為什么會這樣??
uj5u.com熱心網友回復:
您懶惰地加載課程,但因為您通過線路參考它們
System.out.println("luv2code: Courses: " tempInstructor.getCourses());
他們被加載了。
通過添加到您的hibernate.cfg.xml
<property name="hibernate.show_sql">true</property>
并且不要從講師那里獲得課程,然后您會發現它們實際上是延遲加載的。
uj5u.com熱心網友回復:
哦,另一種驗證方式是在提交事務后呼叫課程。事務是可能發生延遲加載的范圍。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/498174.html
下一篇:DuplicateMappingException包含在將passportId添加到Student物體時由多個邏輯列名參考的物理列名
