JPA 基礎 — 2

WuFeng Chiang
4 min readJun 5, 2017

--

JPA 基礎 — 1 中,我提到:Persistence 生成 EntityManagerFactory,這是規範說的。不過去看 API 文件的話,會發現 Persistence 沒那麼做,它是把這個工作轉給了另一個角色:PersistenceProvider。

來看看 API 的解釋:

也就是說,在一個使用容器(container)的環境下,容器自己會使用 PersistenceProvider 來生成 EntityManagerFactory。

這裡我指討論有容器的部分,為什麼呢?JavaEE 裡,談到的容器指的是 Tomcat/JBoss 之類 JaveEE Web / Business tier 的 web server。如果只談論 container 的部分,會不會把討論範圍只限制於 Web 領域呢?其實不然。因為,在我們使用 Spring Framework 的情形下,所以的 Container,指的是 Spring 本身哦!

我們再回頭看一下 JPA 基礎 — 1 中,最後提及的圖:

https://stackoverflow.com/questions/17031971/what-exactly-is-a-persistence-in-jpa-how-is-it-connected-to-entitymanagerfactor

搭配這張圖來做過結論。

(1) 容器其實是使用 PersistenceProvider 生成 EntityManagerFactory。

(2) 生成 EntityManagerFactory 時,會藉由 PersistenceUnit 讀取 persistence.xml 設定檔中的內容,來決定 EntityManagerFactory 的具體形式。

取得 EntityManagerFactory 後,傳統上可以編寫以下程式碼:

其實程式碼不難懂,只是看來笨重,兩個方法裡,都有四行程式碼是重複的。這程式碼點出兩點:

  1. 使用 EntityManager 進行 transaction 的控制。
  2. 使用 EntityManager 進行 Entity 狀態的轉變。

transaction 指的是 begin ~ commit 之間的做的事,無論有幾件,要嘛全部做完,要嘛全部不做。若做完幾件事後,因為下一件事無法完成,就把做完的幾件事,全部 undo 回去。這說明了,在 begin 前的程式碼執行狀態要先被存一份下來,在 commit 後才能被新的狀態置換掉。

transaction 的概念很像醫生開刀;要嘛就開完,若是中途發現腫瘤過大無法進行手術,也得把器官縫合回去。總之,沒有做一半的。

不過每個方法有四行是重複的,將近佔了方法的一半行數,還是挺糟的。怎麼解呢?支援 AOP 的容器,或是使用語言層面的 Lambda。

Spring 支援了使用 Proxy pattern 實作的 AOP。

--

--