當實體包含集合屬性(如 Set<Email>),僅需讀取主表字段(如 name)時,若一次性加載所有關聯集合,將造成不必要的資料庫查詢與記憶體開銷。
// 僅訪問 name
User user = (User) session.load(User.class, 1);
System.out.println(user.getName());
啟用 lazy(預設):
Hibernate: select user0_.id, user0_.name from user user0_ where user0_.id=?
關閉 lazy(lazy="false"):
Hibernate: select user0_.id, user0_.name from user user0_ where user0_.id=?
Hibernate: select emails0_.id, emails0_.address from email emails0_ where emails0_.id=?
<set name="emails" table="email" lazy="true"> <!-- 預設即 true -->
<key column="id"/>
<element type="java.lang.String" column="address"/>
</set>
User user = (User) session.load(User.class, 1);
System.out.println(user.getName()); // 未觸發
Iterator it = user.getEmails().iterator(); // 此處觸發 SQL 查詢
while (it.hasNext()) System.out.println(it.next());
輸出 SQL 顯示:首次查詢 user,調用 iterator() 時才查詢 email 集合。
Session 關閉後訪問未初始化集合 將拋出異常:
session.close();
Iterator it = user.getEmails().iterator(); // 拋出 LazyInitializationException
Hibernate.initialize(user.getEmails()) 強制加載。延遲初始化是效能優化利器,但需配合 Session 管理策略。理解觸發時機、異常成因與解決方案,是 Hibernate 開發必修課。