Java持久化API

Java持久化API（JPA）是一個Java應用程式接口規範，描述了使用Java標準版平台（Java SE）和Java企業版平台（Java EE）的應用中的關係數據的管理。

持久化，在這裡包括三個層面的意思：

- API本身，定義在`javax.persistence`包內
- Java持久化查詢語言（JPQL）
- 對象/關係元數據

JPA的參考實現是EclipseLink。

## 歷史背景

2006年5月11號，JPA 1.0規範作為JCP JSR 220的一部分最終被發布。JPA 2.0規範，在2009年12月發布（Java EE 6平台，依賴於JPA 2.0）。JPA 2.1規範，在2013年4月22日發布（Java EE 7平台，依賴於JPA 2.1）。JPA 2.2規範，於2017年夏季發布。

## 實體

持久化實體是一個輕量級的Java類，其狀態通常持久地保存到關係資料庫的表中。這種實體的實例對應於表中的各個行。實體之間通常有關係，這些關係通過對象/關係元數據表示。可以在實體類文件中直接使用注釋來指定這種關係，也可以在隨應用程式分發的單獨XML描述文件中指定。

### 範例

用注釋宣告含有對象/關係元數據的實體類 (省略import語句、setters/getters方法)

```java
@Entity
public class Person {
    @Id
    private long id;
    private String firstName;
    private String lastName;
    private int age;
}
```

`@Entity` 宣告類為一個實體，`@Id` 宣告該屬性為主鍵，例如: 此處的`id` 就是這個實體的主鍵。另外可以再用其他 注釋來宣告元數據(例如: 使用`Table`來變更預設的資料表名稱)，或建立表與表之間的關聯。

## Java 持久化查詢語言（JPQL）

Java持久化查詢語言（JPQL）對存儲在關係資料庫中的實體進行查詢。查詢在語法上類似於SQL查詢，但是操作的是實體對象而不是直接對資料庫表進行操作。

## 動機

在引入EJB 3.0規範之前，許多企業級Java開發人員使用由持久化框架（例如Hibernate）或數據訪問對象（DAO）提供的輕量級持久化對象，來代替實體bean（EJB的一種）。這是因為在以前的EJB規範中，實體bean需要太多複雜的代碼和繁重的資源占用，並且由於bean和DAO對象或持久化框架之間的原始碼中的互連和依賴性，它們只能在Java EE應用程式伺服器中使用。因此，最初在第三方持久性框架中提供的許多功能都被合併到Java持久化API中，並且從2006年開始，像Hibernate（版本3.2）和TopLink Essentials這樣的項目已經實現Java持久化API規範。

## 相關技術

### 企業 JavaBeans（EJB）

EJB 3.0規範（本身是Java EE 5平台的一部分）包含Java持久化API的定義。無論如何，終端用戶不需要EJB容器或Java EE應用程式伺服器即可運行使用此持久性API的應用程式。Java持久化 API的未來版本將在單獨的JSR和規範中定義，而不是在EJB JSR /規範中定義。

Java持久化API取代了EJB 2.0 CMP（持久化管理容器）的持久性解決方案

### Java數據對象的API

Java持久化API作為統一Java Data Objects API和EJB 2.0容器管理持久性（CMP）API的一部分來開發。截至2009年，支持這些API的大多數產品都支持Java持久化API。

Java持久化API僅為關係資料庫管理系統提供持久化特性。也就是說，JPA專注於對象關係映射（ORM）（請注意，除了關係資料庫之外，還有JPA提供程式支持其他資料庫模型，但這超出了JPA的設計範圍）。有關JPA角色的說明，請參閱JPA 2規範第1節簡介，其中非常清楚地說明「這項工作的技術目標是為Java應用程式開發人員提供一個對象/關係映射工具，使用Java領域模型來管理關係資料庫。」

Java數據對象規範支持ORM，以及對其他類型的資料庫模型的持久化，例如平面文件資料庫和NoSQL資料庫，包括文檔資料庫，圖形資料庫，以及字面上任何其他可想到的數據存儲。

### 服務數據對象 API

Java持久化API的設計者旨在提供關係持久化，其中許多關鍵領域來自對象關係映射工具，如Hibernate和TopLink。Java持久化API改進並取代了EJB 2.0，其體現在EJB 3.0中。服務數據對象（SDO）API（JSR 235）與Java持久化API有著截然不同的目標，被認為是互補的。SDO API專為面向服務的體系結構，多種數據格式而非關係數據和多種程式語言而設計。JCP管理SDO API的Java版本；SDO API的C++版本通過OASIS進行管理。

### Hibernate

Hibernate為Java提供了一個開源的對象關係映射框架。版本3.2及更高版本提供了Java 持久化 API的實現。Gavin King創立了Hibernate項目。他代表JBoss參加JSR 220，這是負責開發JPA的JCP專家組。這引發了圍繞JPA和Hibernate之間關係的持續爭議和猜測。Sun Microsystems表示，這些想法來自幾個框架，包括Hibernate和Java 數據對象。

### Spring Data JPA

抽象存儲庫的實現是Java應用程式框架Spring的領域驅動設計的關鍵構建塊。透明地支持所有可用的JPA實現，並支持CRUD操作以及方便地執行資料庫查詢。

## JPA 2.0

2007年7月，JPA 2.0 在JCP的JSR 317請求中作為新版本開發。2009年12月10日，JPA 2.0被批准為最終正式標準。JPA 2.0的重點是提供一些流行的ORM供應商中存在的特性，但在JPA 1.0中不能獲得一致認可。

主要特性包括：

- 擴大對象關係功能的映射
- 支持內嵌對象的收集，通過多對一的關係映射來連接ORM
- 有序列表
- 訪問類型的組合
- 一種標準查詢API
- 標準化的SQL提示
- 標準化的附加元數據，以支持DDL生成
- 支持驗證
- 支持共享對象的高速緩存

支持JPA 2.0的供應商:

- Batoo JPA
- DataNucleus (formerly JPOX)
- EclipseLink (formerly Oracle TopLink)
- IBM, for WebSphere Application Server
- JBoss with Hibernate
- Kundera
- ObjectDB
- OpenJPA
- OrientDB from Orient Technologies
- Versant Corporation JPA (not relational, object database)

## JPA 2.1

2011年7月，JPA 2.1 在JCP的JSR 338請求中作為新版本開發。2013年5月22日，JPA 2.1被批准為最終正式標準。

主要特性包括：

- 轉換器-允許自定義的代碼去裝換不同的資料庫和數據類型。
- 標準Update/Delete-允許通過標準API批量更新和刪除。
- 實體圖表-允許獲取部分或合併對象。
- JPQL/標準增強-算子查詢，通用資料庫的功能，Join 聯合查詢，TREAT 選項。
- 模式生成
- 存儲過程，允許查詢被定義為資料庫的存儲過程。

支持JPA 2.1 的供應商:

- DataNucleus
- EclipseLink
- Hibernate

## JPA 2.2

2017年，JPA 2.2在JCP的JSR 338請求中作為維護版本發布開發。維護審查已於2017年6月19日獲得批准。

主要特性包括：

- 給所有有關的注釋添加`@Repeatable`
- 允許所有JPA注釋可用於元的注釋。
- 添加查詢結果流處理能力
- 允許AttributeConverters的CDI注入
- 支持Java 8的日期和時間類型

支持JPA 2.2的供應商:

- DataNucleus
- EclipseLink（自2.7版本以來）
- Hibernate （自5.3版本以來）

## JPA的未來工作

未來的JPA規範資訊可在此處獲得：

- JPA Specification Mailing Lists
- JPA Specification JIRA

2015年11月，Linda DeMichiel在javaee-spec使用者郵件中宣布Lukas Jungmann接任規範化主管。Linda的聲明還表示，「計劃在Java EE 8時間框架內為JPA 2.2做MR」。

## 工具

- NetBeans Jeddict
- Eclipse JPA（Dali）

## 外部連結

### 一般資訊

- Documentation for the final version of the EJB3 spec (called JSR220)
- GlassFish's Persistence page
- JCP Persistence page

### 教程

- Java EE 6 Persistence API Javadoc
- Java EE 6 Persistence API tutorial
- Java EE 7 Persistence API Javadoc
- Java EE 7 Persistence API tutorial
- JPA Tutorial by Prasad Kharkar
- JPA Tutorial from Java Code Geeks
- JPA Tutorial using OpenJPA as implementation
- Persistence in the Java EE 5 tutorial