首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 實戰避坑指南:generator 不一致導致連接失敗與 ClassCastException 解析

     編輯:Java 相關知識

問題一:generator 策略不一致導致 NameNotFoundException

現象

Tomcat + Struts + Hibernate + SQL Server 專案,啟動報錯:

javax.naming.NameNotFoundException: Name hibernate_connection_factory is not bound in this Context

無法連接數據庫。

根因

多個 .hbm.xml 映射文件中 <id> 的 generator 策略不一致:

<!-- 文件 A -->
<generator class="identity"/>

<!-- 文件 B -->
<generator class="native"/>

identity 依賴數據庫自增列(SQL Server 支持),native 則由 Hibernate 根據方言自動選擇(可能選 sequence 或 hilo)。混用導致 SessionFactory 構建時對連接工廠的需求衝突,最終拋出 JNDI 綁定異常。

解決方案

  1. 統一所有映射文件的 generator 策略,推薦用 native(跨數據庫遷移友好)或明確指定 identity(僅限支持自增的 DB)。
  2. 檢查 hibernate.cfg.xml 中 dialect 是否正確:org.hibernate.dialect.SQLServerDialect。
  3. 確認 JNDI 數據源配置(context.xml / web.xml)與 Hibernate 配置一致。

問題二:query.iterate() 返回 Object[] 導致 ClassCastException

現象

[WARN] TypeDAO - java.lang.ClassCastException: com.shjinbang.hibernate.Type
Iterator itr = query.iterate();
while (itr.hasNext()) {
    Object object[] = (Object[]) itr.next();  // 拋出異常
    User user = (User) object[0];
    ...
}

根因

HQL 查詢 from User 單表無關聯時,iterate() 直接返回實體對象(User),而非 Object[]。強轉為數組導致 ClassCastException。

正確寫法

Iterator itr = query.iterate();
while (itr.hasNext()) {
    Object obj = itr.next();           // 直接接收 Object
    User user = (User) obj;            // 安全轉型
    userForm.setUserId(user.getUserId());
    ...
}

何時會返回 Object[]?

  • 多表連接查詢:select u, r from User u join u.roles r
  • 投影查詢:select u.id, u.name from User u
  • 報表類聚合查詢

這些場景下每行結果包含多個字段/實體,Hibernate 以 Object[] 封裝。

最佳實踐檢查清單

場景推薦做法
主鍵生成策略全項目統一 native 或按 DB 統一 identity/sequence
單表查詢list() 返回 List<Entity>;iterate() 直接轉實體
多表/投影查詢接收 List<Object[]>,按下標取值
性能優化僅遍歷用 iterate()(延遲加載),需全加載用 list()
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved