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

Hibernate 執行順序解析:save/delete/save 為何非 insert/insert/delete

     編輯:程式設計疑難解答

代碼與現象

session.beginTransaction();
Person p = new Person("王三", 22, "男", "北京");
session.save(p);      // 1
session.delete(p);    // 2
p.setId(null);
session.save(p);      // 3
session.getTransaction().commit();

控制台 SQL 順序:

INSERT ...  -- save(p) 第1次
DELETE ...  -- delete(p)
INSERT ...  -- save(p) 第2次

疑問:Hibernate 不是延遲執行、按「INSERT 先於 DELETE」排序嗎?

核心原理:Action Queue 與執行順序

Hibernate Session 內部維護 **Action Queue**,不同操作對應不同 Action 類型,執行優先級固定:

  1. EntityInsertAction (save)
  2. EntityUpdateAction
  3. EntityDeleteAction (delete)
  4. CollectionRemoveAction
  5. CollectionUpdateAction
  6. CollectionRecreateAction
  7. EntityIdentityInsertAction (save 產生 ID)

**但**優先級僅決定**同類實體**的排序。**同一實體實例**的多次操作,**按代碼調用順序**入隊,flush 時**按入隊順序**執行。

本例逐步分析

  1. save(p) → 入隊 InsertAction(p 為 transient,賦予 ID)。
  2. delete(p) → 入隊 DeleteAction(p 現為 persistent)。
  3. setId(null) + save(p) → p 變回 transient,**新增**一個 InsertAction(視為新實體)。
  4. Flush 時按隊列順序:Insert → Delete → Insert。

關鍵結論

  • Hibernate **不會**跨實體實例重排不同操作類型;**同一實例的多次操作嚴格遵循調用順序**。
  • setId(null) 將持久化對象變為臨時態,**極不推薦**;應新建對象:Person p2 = new Person(...)。
  • 若需「刪除舊、插入新」,應分兩個事務,或用 session.evict(p) 後新建對象。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved