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

JPA 實體生命週期與 EntityManager 核心 API 完全圖解

     編輯:Java 相關知識

JPA 實體在持久化上下文中經歷四種狀態轉換,`EntityManager` 提供完整 API 控制生命週期。本文系統梳理狀態機、核心方法語義與級聯行為。

四大實體狀態與轉換

新建態 
  | persist()
  v
受控態 <---------- merge() -------- 游離態
  |  remove()           find() / query()
  v
刪除態
狀態特徵持久化上下文關聯
新建態剛 `new`,無 ID,未關聯無
受控態有 ID,已關聯,變更自動同步有
游離態有 ID,曾受控但已脫離無
刪除態已標記刪除,提交時從 DB 移除有 (直到提交)

EntityManager 核心 API 語義表

方法狀態轉換關鍵語義
`persist(entity)`新建 → 受控事務提交時 INSERT;已受控無效果;刪除態→受控;游離態拋異常
`remove(entity)`受控 → 刪除事務提交時 DELETE;級聯刪除 (cascade=REMOVE/ALL);新建/刪除態忽略;游離態拋異常
`merge(entity)`游離 → 受控返回新受控實例;複製狀態至上下文;新建態視同 persist
`find(Class, pk)`— → 受控主鍵查詢,返回受控實例;未找到返回 null
`flush()`受控 → DB 同步強制同步變更至資料庫,不提交事務
`createQuery(jpql)`— → QueryJPQL 查詢,返回 `Query` 執行
`createNativeQuery(sql)`— → Query原生 SQL,結果為 `List`

Query 介面關鍵方法

  • `getSingleResult()`:單一結果,無/多結果拋異常
  • `getResultList()`:多結果 `List`
  • `setParameter(pos/name, value)`:參數綁定
  • `setMaxResults(max)`:分頁限制
  • `executeUpdate()`:執行 UPDATE/DELETE JPQL

級聯操作規則

  • `persist()`、`merge()`、`remove()`、`refresh()`、`detach()` 均可透過 `cascade` 屬性傳遞至關聯實體
  • `CascadeType.ALL` = PERSIST + MERGE + REMOVE + REFRESH + DETACH
  • 集合關聯 (`List`) 級聯需集合元素實體支援

常見陷阱與最佳實踐

  1. 游離實體修改後未 merge:變更不會同步資料庫,必須 `merge()` 回受控態
  2. 長事務中實體變為游離:Session/EntityManager 關閉導致,使用 `merge()` 重新附著
  3. 避免在受控實體上手動設 ID:交由持久化提供者策略生成
  4. 批次操作用 `flush()` + `clear()`:防止一級快取撐爆記憶體
  5. 樂觀鎖 `@Version`:防止併發更新覆蓋,合併時自動檢查

程式碼範例:完整生命週期

// 新建
Account acc = new Account("user1");
em.persist(acc);           // 受控
em.flush();                // 同步取得生成 ID

// 查詢 (新事務/新 EntityManager)
Account found = em.find(Account.class, acc.getId()); // 受控

// 修改
found.setEmail("new@mail.com"); // 自動髒檢查,提交時 UPDATE

// 刪除
em.remove(found);          // 刪除態
em.getTransaction().commit(); // 真正 DELETE

掌握狀態機與 API 語義,是寫出正確、高效 JPA 程式碼的關鍵。

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