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

Hibernate 註解實體:查詢新增正常但無法刪除修改的排查與解決

     編輯:程式設計綜合問答

現象描述

使用 Hibernate 註解映射實體類時,發現 save()、find()、list() 操作正常,但 delete() 和 update() / merge() 執行後資料庫數據未變更,且控制台無任何錯誤日誌或異常拋出。

常見原因分析

1. 缺少交易管理

Hibernate 的寫操作必須在交易中執行。若未開啟交易或交易未提交:

// 錯誤示範
session.delete(entity);  // 無交易包裹,操作不生效

// 正確寫法
Transaction tx = session.beginTransaction();
try {
    session.delete(entity);
    tx.commit();
} catch (Exception e) {
    tx.rollback();
    throw e;
}

2. 實體類缺少 @Id 或主鍵生成策略錯誤

刪除/修改依賴主鍵定位記錄。檢查:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)  -- 或 SEQUENCE, AUTO
    private Long id;
    // ...
}

3. 實體處於游離狀態

若實體來自其他 Session 或經過序列化/反序列化,需先合併:

User managed = session.merge(detachedUser);  // 重新關聯到當前 Session
session.delete(managed);

4. 資料庫層面約束阻攔

  • 外鍵約束:存在關聯記錄導致刪除失敗(需先刪除子表或配置級聯)
  • 觸發器/規則:資料庫層面攔截 DML 操作
  • 權限不足:連接使用者缺少 DELETE/UPDATE 權限

5. Hibernate 配置問題

<property name="hibernate.hbm2ddl.auto">update</property>  -- 確保非 validate
<property name="hibernate.show_sql">true</property>  -- 開啟 SQL 日誌觀察是否發送語句

排查步驟

  1. 開啟 show_sql=true 與 format_sql=true,確認 Hibernate 是否真正發送了 DELETE/UPDATE 語句
  2. 檢查資料庫日誌(如 MySQL general_log, Oracle audit)驗證語句是否執行
  3. 在 Service 層添加 @Transactional 註解(Spring 環境)或手動管理交易
  4. 嘗試在資料庫客戶端手動執行對應 SQL,觀察是否報錯
  5. 檢查實體類 equals() / hashCode() 實現是否基於主鍵

解決案例

開發者最終發現是 未在 Service 方法上添加 @Transactional 註解,導致交易未提交。補全註解後問題解決。另一常見案例為 使用 MyISAM 引擎的 MySQL 表不支援交易,需轉換為 InnoDB。

最佳實踐建議

  • 統一使用聲明式交易管理(Spring @Transactional)
  • 實體類實作 Serializable 並基於業務主鍵實現 equals/hashCode
  • 整合測試覆蓋 CRUD 全流程,包含邊界條件
  • 生產環境關閉 show_sql,改用 P6Spy 或 datasource-proxy 記錄慢 SQL
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved