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

Hibernate 4 save/update 無效不報錯:Timestamp/Date 類型映射陷阱排查實錄

     編輯:Java 相關知識

在 SSH 電商專案開發中,遭遇詭異現象:session.save() / update() 執行無異常、無 SQL 輸出、數據庫無變更。經排查發現根因在於 POJO 日期字段類型與數據庫列類型映射不匹配,本文記錄完整排查思路與解決方案。

一、 現象描述

  • 其他實體 CRUD 正常,僅 Product 實體持久化失效
  • 控制台無錯誤堆棧,show_sql=true 無對應 INSERT/UPDATE 輸出
  • 事務由 Spring 統一管理,配置無誤
  • 主鍵策略 auto_increment 正常

二、 排查過程

1. 疑點鎖定:日期字段映射

數據庫表結構:

date timestamp default CURRENT_TIMESTAMP

POJO 映射:

@Column(name = "date", nullable = false, length = 19)
private Timestamp date;

2. 關鍵發現

Hibernate 4 對 java.sql.Timestamp 映射 TIMESTAMP 列存在已知兼容性問題:類型解析器可能誤判為不可寫入屬性,導致實體處於「只讀」狀態,持久化操作被靜默忽略。

3. 解決方案

將 POJO 字段類型改為 java.util.Date:

@Temporal(TemporalType.TIMESTAMP)
@Column(name = "date", nullable = false)
private Date date;

Hibernate 會自動根據 @Temporal 註解將 Date 轉換為數據庫 TIMESTAMP,避免類型衝突。

三、 核心教訓

  1. 異常不報不等於成功:Hibernate 某些情況下會吞掉約束違規/類型不匹配異常
  2. 映射類型要精確:優先使用 java.util.Date + @Temporal,避免直接用 java.sql.* 類型
  3. 排查思路:從對象入手:當 SQL 層面無異常時,重點檢查實體映射、字段類型、註解配置
  4. 開啟詳細日誌:log4j.logger.org.hibernate=DEBUG 可見實體狀態變遷

四、 避坑檢查清單

  • [ ] 所有日期字段統一用 java.util.Date + @Temporal
  • [ ] @Column 的 length 屬性對日期類型無效,需移除
  • [ ] 實體類實現 Serializable,定義 serialVersionUID
  • [ ] 單元測試覆蓋每個實體的 CRUD 操作

這個坑看似微小,卻能耗費數小時排查。記住:映射類型不匹配是 Hibernate 靜默失效的頭號殺手。

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