首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Hibernate 多對一查詢無法取得關聯物件:Lazy Loading 與映射配置排查

     編輯:程式設計疑難解答

問題現象

Medicine(多方)關聯 Category(一方),查詢 Medicine 時 medicine.category 為 null 或拋出 LazyInitializationException。

常見原因與修正

原因檢查點修正
映射檔 many-to-one 缺失或屬性錯誤medicine.hbm.xml 是否有 <many-to-one name="category" column="CATEGORY_ID" class="Category"/>補全映射,確認 column 對應外鍵欄位
Lazy Loading 預設開啟,Session 已關閉存取 category 時 Session 是否開啟1. 映射加 lazy="false"(急切載入)
2. 或在 Service 層用 Hibernate.initialize(medicine.category)
3. 或開啟 Open Session In View
外鍵欄位為 NULL資料庫 MEDICINE.CATEGORY_ID 是否有值補齊資料或允許 nullable
雙向關聯 set 缺少 inverse="true"Category.hbm.xml 的 <set name="meds" inverse="true">加上 inverse="true" 讓多方維護關係

標準映射範例

<!-- Medicine.hbm.xml -->
<class name="Medicine" table="MEDICINE">
    <id name="id" column="ID"><generator class="native"/></id>
    <many-to-one name="category" column="CATEGORY_ID" class="Category" lazy="false"/>
</class>

<!-- Category.hbm.xml -->
<class name="Category" table="CATEGORY">
    <id name="id" column="ID"><generator class="native"/></id>
    <set name="meds" table="MEDICINE" inverse="true" lazy="true">
        <key column="CATEGORY_ID"/>
        <one-to-many class="Medicine"/>
    </set>
</class>

存取方式

Medicine med = session.get(Medicine.class, id);
Category cat = med.getCategory(); // lazy=false 直接可用
// 或
Hibernate.initialize(med.getCategory()); // lazy=true 時在 session 開啟期間初始化

進階建議

  • 改用 JPA 註解(@ManyToOne(fetch = FetchType.LAZY))+ Spring Data JPA,映射更直觀。
  • DTO 投影查詢:SELECT new MedicineDTO(m.id, m.name, c.name) FROM Medicine m JOIN m.category c 避免載入完整實體圖。
  • 生產環境**關閉 Open Session In View**,明確控制 Session 邊界。

總結

多對一查不到關聯物件,90% 是 Lazy Loading + Session 關閉 或 映射檔 column/class 錯誤。檢查映射、決定載入策略(急切/延遲+初始化)、確認資料庫外鍵有值,即可解決。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved