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

Hibernate Session 核心 API 深度解析:三大狀態轉換與常用方法實戰

     編輯:Java 綜合教學

Session 介面定位

Session 是 Java 應用與 Hibernate 框架交互的核心介面,提供映射實體類實例的增刪改查操作。每個實例處於三種狀態之一:

  • Transient(瞬時態):從未持久化,不在 Session 快取中
  • Persistent(持久態):在 Session 快取中,與資料庫記錄對應
  • Detached(遊離態):曾為持久態,現不在 Session 快取中

狀態轉換圖譜

來源狀態目標狀態方法SQL
TransientPersistentsave()、persist()、saveOrUpdate()INSERT
PersistentTransientdelete()DELETE
Persistent—修改屬性 → flush()UPDATE
DetachedPersistentupdate()、saveOrUpdate()、lock()、replicate()UPDATE/INSERT
Transient/DetachedPersistent (新物件)merge()INSERT/UPDATE

關鍵差異:merge() 會複製屬性到新建的持久化物件,原物件不變;saveOrUpdate() 則嘗試重用原物件。

線程安全與事務範本

Session 實作類非線程安全,每個線程/事務必須從 SessionFactory 獲取獨立實例。

Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();
    // 業務操作...
    tx.commit();
} catch (Exception e) {
    if (tx != null) tx.rollback();
    throw e;
} finally {
    sess.close();
}

若 Session 拋出異常,事務必須回滾,且 Session 需丟棄(內部狀態可能與資料庫不一致)。

核心方法詳細解析

1. save() — 持久化瞬時物件

@Test
public void testSave() {
    User user = new User();
    user.setBirthday(new java.sql.Date(0));
    user.setName("binyulan");
    // native 策略,MySQL 自增主鍵,無需設定 id
    Serializable id = session.save(user); // 回傳生成的主鍵
}

2. persist() — JPA 標準化持久化

@Test
public void testPersist() {
    User user = new User();
    user.setBirthday(new java.sql.Date(0));
    user.setName("binyulan");
    user.setId(13); // 若設定 id 會拋出 PersistentObjectException
    session.persist(user); // 無回傳值
}

異常提示 detached entity passed to persist,推測:只要設定了 id,Hibernate 視為遊離態,即使未持久化過。

3. merge() — 合併與複製語義

// 情況 A:無 id → INSERT,回傳新持久化物件
User user = new User(); user.setName("binyulan2");
User user1 = (User) session.merge(user);
System.out.println(user1 == user); // false,user 不在 Session 中

// 情況 B:有 id → 先 SELECT,再 UPDATE 或 INSERT
user.setId(20L); // 假設 DB 有 id=20
User user2 = (User) session.merge(user); // UPDATE

user.setId(123456789L); // DB 無此 id
User user3 = (User) session.merge(user); // INSERT

merge() 總是回傳新建的持久化物件,原物件保持瞬時/遊離態。

未完待續...

更多方法(load()、get()、update()、delete()、lock()、refresh()、evict()、clear()、flush())及最佳實踐,敬請關注後續章節。

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