---
# System prepended metadata

title: API
tags: [Java, JPA, Spring]

---

# API
###### tags: `JPA` `Spring` `Java`
**Persistence** 類用於取得EntityManagerFactory實例。
包含靜態方法 createEntityManagerFactory
該方法有兩個重載版本
一個參數的 : 以JPA配置文件persistence.xml中的persistence-unit為參數
兩個參數的 : 第一個參數同上，第二個為存放JPA相關屬性的Map

**EntityManagerFactory**介面主要用來建立EntityManage實例
該介面定義了四個方法
createEntityManager() : 建立EntityManage
createEntityManager(Map m) : 建立EntityManage，Map用於提供EntityManager屬性
isOpen() : 檢查EntityManagerFactory是否為開啟狀態
close() : 關閉EntityManagerFactory。關閉後繼續調用則會拋IllegalStateException

**EntityManager#find** 類似於hibernate session的 get
當執行find時就直接向DB發SQL

**EntityManager#getReference** 類似於 hibernate session的 load。  呼叫後取得的是一個代理對象，當要用到裡面的屬性時才向DB發SQL。有可能造成懶加載問題(在取得屬性前就把EntityManagerFactory關閉)

**EntityManager#persist** 類似於hibernate的 save
使物件由臨時狀態轉為持久化狀態。和hibernate的save不同之處為: 如果對象有ID 則不能insert會拋出一個錯誤 

**EntityManager#remove** 類似於hibernate的 delete 
把對象對應的紀錄從資料庫移除，但注意:該方法只能移除持久化對象而hibernate的delete方法實際上還可以移除游離對象

實體狀態:
新建 : 新建的物件，尚未擁有持久化主鍵
持久化 : session中擁有資料庫持久化主鍵
游離 : 資料庫中有持久化主鍵但session沒有
刪除 : 刪除持久化對象


**EntityManager#merge** 用於處理entity同步。資料庫的插入及更新 類似於hibernate saveOrUpdate 但更為複雜
**情境1.** 傳入一個**新建**狀態的物件則會將新建狀態的物件複製到一個新的物件並且對新的物件進行持久化操作並回傳

**情境2.**傳入一個**游離**狀態的物件且有ID
			1. 若在EntityManager session中沒有該對象
			2. 資料庫中也沒有對應紀錄
			3. JPA建立一個新的物件並將游離對象複製過去
			4. 執行insert

**情境3.**傳入一個**游離**狀態的物件且有ID
			1. 若在EntityManager session中沒有該對象
			2. 資料庫中也有對應紀錄
			3. JPA會查詢對應紀錄得到一個持久化物件並且將傳入的游離狀態的物件複製到查詢出來的物件
			4. 執行update

**情境4.**傳入一個**游離**狀態的物件且有ID
			1. 若在EntityManager session中有該對象
			2. JPA會將游離狀態的物件複製到EntityManager session的對象中
			3. 執行update

**EntityManager#flush** 同步所有持久化物件
**EntityManager#refresg(Object entity)** 同步指定 持久化物件
**EntityManager#clear** 清除持久上下文環境，斷開所有關離的實體。若有未提交的更新則被取消

**EntityTransaction**介面用來管理資源層實體管理器的事務操作。通過實體管理器的getTransaction方法取得實例