2003 年 JavaOne 大會上,JDO 與 CMP 之爭成為焦點。本文基於 David Jordan 與 Craig Russell 合著《Java Data Objects》第 17 章核心觀點,結合 JDO 1.0 與 EJB 2.1 CMP 規範特性,為架構師提供決策框架。
| 維度 | JDO (Java Data Objects) | CMP (Container-Managed Persistence) |
|---|---|---|
| 核心哲學 | POJO 持久化:純 Java 物件透明持久化 | 元件模型:實體 Bean 作為分散式元件 |
| 執行環境 | 任意層(單層、雙層、多層、EJB 容器內/外) | 強制 EJB 容器內,Session Bean 後方 |
| 遠程介面 | 無直接定義,由容器/框架實現分散式行為 | 原生遠程/本地介面,容器管理分散式語義 |
| 開發除錯 | 部署前可單元測試,IDE 友好 | 需部署至應用伺服器才能測試,週期長 |
| 可移植性 | 視廠商可選功能支援度而異 | Bean 類與描述檔標準化,移植性較高 |
範例:MediaItem 關聯抽象 MediaContent 及子類 Movie、Game。CMP 必須建立兩個獨立關聯,每個業務方法雙重處理。
get/set 方法,實際存取由工具生成的實作類完成,原始碼中無法直接存取欄位| 特性 | JDOQL | EJB QL |
|---|---|---|
| 語法基礎 | Java 語法子集,型別安全 | SQL 類似語法,字串基礎 |
| 查詢對象 | 持久化類與欄位直接引用 | 實體 Bean 抽象綱要名稱 |
| 多型查詢 | 原生支援 | 不支援(因無繼承) |
| 導航路徑 | 物件圖導航自然表達 | 關聯路徑導航 |
| 批次更新/刪除 | JDO 2.0 引入 | EJB 3.0 / JPA 引入 |
兩者皆採「讀-改-寫」模式,非完整 DML,主要用於查找物件後在記憶體中修改再持久化。
歷史證明,JDO 的 POJO 哲學與 CMP 的容器服務最終在 EJB 3.0 (JPA) 中融合:
JDO 贏在「物件純粹性、開發敏捷性、測試友好、繼承多型」;CMP 贏在「分散式元件語義、關聯自動管理、標準化移植性」。2003 年的選擇本質是:領域模型中心 vs 元件介面中心。現代架構中,JPA 已成為事實標準,但理解這場歷史辯論有助於把握持久化框架設計的核心權衡——純粹物件模型與容器服務的邊界在哪裡? 這正是每個架構師必須回答的問題。