數據的唯一性是所有應用程序非常基本的要求,由開發者或者用戶來維護這種 唯一性存在著較大的風險,因此,由系統自動產生唯一標識是一種常見的做法。 OpenJPA 中支持四種不同的實體標識自動生成策略:
容器自動生成的實體 標識;
使用數據庫的自動增長字段生成實體標識;
根據數據庫序 列號(Sequence)技術生成實體標識;
使用數據庫表的字段生成實體標識 ;
這四種方式各有優缺點,開發者可以根據實際情況進行選擇。
可選擇的注釋
要讓容器和數據庫結合管理實體標識的自動生成,根據實際 情況的不同,開發者可以選擇 javax.persistence.* 包下面的 GeneratedValue 、SequenceGenerator、TableGenerator 三個注釋來描述實體的標識字段。
@javax.persistence.GeneratedValue
每一個需要自動生成實體標 識的實體都需要為它的實體標識字段提供 GeneratedValue 注釋和相應的參數, OpenJPA 框架會根據注釋和參數來處理實體標識的自動生成。
使用 GeneratedValue 注釋自動生成的實體標識可以是數值類型字段如 byte、short、 int、long 等,或者它們對應的包裝器類型 Byte、Short、Integer、Long 等, 也可以是字符串類型。
GeneratedValue 注釋可以支持兩個屬性 strategy 和 generator。
strategy
strategy 是 GenerationType 類型的枚 舉值,它的內容將指定 OpenJPA 容器自動生成實體標識的方式。strategy 屬性 可以是下列枚舉值:
GeneratorType.AUTO
表示實體標識由 OpenJPA 容器自動生成,這也是 Strategy 屬性的默認值。
GenerationType.IDENTITY
OpenJPA 容器將使用數據庫的自增長字 段為新增加的實體對象賦唯一值,作為實體的標識。這種情況下需要數據庫提供 對自增長字段的支持,常用的數據庫中,HSQL、SQL Server、MySQL、DB2、Derby 等數據庫都能夠提供這種支持。
GenerationType.SEQUENCE
表示使用數據庫的序列號為新增加的實體對 象賦唯一值,作為實體的標識。這種情況下需要數據庫提供對序列號的支持,常 用的數據庫中,Oracle、PostgreSQL 等數據庫都能夠提供這種支持。
GenerationType.TABLE
表示使用數據庫中指定表的某個字段記錄實體 對象的標識,通過該字段的增長為新增加的實體對象賦唯一值,作為實體的標識 。
String generator
generator 屬性中定義實體標識生成器的名 稱。如果實體的標識自動生成策略不是 GenerationType.AUTO 或者 GenerationType.IDENTITY,就需要提供相應的 SequenceGenerator 或者 TableGenerator 注釋,然後將 generator 屬性值設置為注釋的 name 屬性值。
@javax.persistence.SequenceGenerator
如果實體標識的自動生 策略是 GenerationType.SEQUENCE,開發者需要為實體標識字段提供 SequenceGenerator 注釋,它的參數描述了使用序列號生成實體標識的具體細節 。該注釋支持以下四個屬性:
表 1. SequenceGenerator 注釋屬性說明
屬性 說明 name 該屬性是必須設置的屬性,它表示了 SequenceGenerator 注釋在 OpenJPA 容器 中的唯一名稱,將會被 GeneratedValue 注釋的 generator 屬性使用。將實體標 識的自動生成委托給數據庫的序列號特性時,實體標識字段的 GeneratedValue 注釋的 generator 屬性的值必須和某個 SequenceGenerator 注釋的 name 屬性 值保持一致。 sequenceName 實體標識所使用的數據 庫序列號的名稱。該屬性是可選的,如果我們沒有為該屬性設置值,OpenJPA 框 架將自動創建名為 OPENJPA_SEQUENCE 的序列號。如果一個 OpenJPA 容器中管理 的多個實體都選擇使用序列號機制生成實體標識,而且實體類中都沒有指定標識 字段的 sequenceName 屬性,那麼這些實體將會共享系統提供的默認名為 OPENJPA_SEQUENCE 的序列號。這可能引起實體類編號的不連續。我們可以用下面 的這個簡單例子說明這種情況:假設 OpenJPA 容器中存在兩個實體類 Dog 和 Fish,它們的實體標識字段都是數值型,並且都選擇使用序列號生成實體標識, 但是實體類中並沒有提供 sequenceName 屬性值。當我們首先持久化一個 Dog 對 象時,它的實體標識將會是 1,緊接著我們持久化一個 Fish 對象,它的實體標 識就是 2,依次類推。 initialValue 該屬性設置所 使用序列號的起始值。 allocationSize 一些數據庫 的序列化機制允許預先分配序列號,比如 Oracle,這種預先分配機制可以一次性 生成多個序列號,然後放在 cache 中,數據庫用戶獲取的序列號是從序列號 cache 中獲取的,這樣就避免了在每一次數據庫用戶獲取序列號的時候都要重新 生成序列號。allocationSize 屬性設置的就是一次預先分配序列號的數目,默認 情況下 allocationSize 屬性的值是 50。
@javax.persistence.TableGenerator
如果實 體標識的自動生策略是 GenerationType.TABLE,開發者需要為實體標識字段提供 TableGenerator 注釋,它的參數描述了使用數據庫表生成實體標識的具體細節。 該注釋支持下列屬性:
表 2. TableGenerator 注釋屬性說明
屬性 說明 name 該屬性是必須設置的屬性,它表示了 TableGenerator 注釋在 OpenJPA 容器中的 唯一名稱,將會被 GeneratedValue 注釋的 generator 屬性所使用。將實體標識 的自動生成委托給數據庫表時,實體標識字段的 GeneratedValue 注釋的 generator 屬性的值必須和某個 TableGenerator 注釋的 name 屬性值保持一致 。 table 該屬性設置的是生成序列號的表的名稱。 該屬性並不是必須設置的屬性,如果開發者沒有為該屬性設置值,OpenJPA 容器 將會使用默認的表名 OPENJPA_SEQUENCES_TABLE 。 schema 該屬性設置的是生成序列號的表的 schema 。該屬性並不是必須設置的屬性,如果開發者沒有為該屬性設置值,OpenJPA 容 器將會默認使用當前數據庫用戶對應的 schema。 catalog 該屬性設置的是生成序列號的表的 catalog。該屬性並不是必須設置的屬性,如果開發者沒有為該屬性設置值, OpenJPA 容器將會使用默認當前數據庫用戶對應的 catalog。 pkColumnName 該屬性設置的是生成序列號的表中的 主鍵字段的名稱,該字段將保存代表每個實體對應的標識值對應的特征字符串。 該屬性並不是必須設置的屬性,如果開發者沒有為該屬性設置值,OpenJPA 容器 將會使用默認值 ID 。 valueColumnName 該屬性設 置的是生成序列號的表中記錄實體對應標識最大值的字段的名稱。該屬性並不是 必須設置的屬性,如果開發者沒有為該 屬性設置值,OpenJPA 容器將會使用默認 值 SEQUENCE_VALUE 。 pkColumnValue 該屬性設置 的是生成序列號的表中的主鍵字段的特征字符串值 ( 比如 customID ),該字段 將保存代表每個實體對應的標識值對應的特征字符串。該屬性並不是必須設置的 屬性,如果開發者沒有為該屬性設置值,OpenJPA 容器將會使用默認值 DEFAULT 。可以為多個實體設置相同的 pkColumnValue 屬性值,這些實體標識的生成將通 過同一列的值的遞增來實現。 initialValue 該屬性 設置的是生成序列號的表實體標識的初始值。該屬性並不是必須設置的屬性,如 果開發者沒有為該屬性設置值,OpenJPA 容器將會使用默認值 0 。 allocationSize 為了降低標識生成時頻繁操作數據 庫造成 的性能上的影響,實體標識生成的時候會一次性的獲取多個實體標識,該 屬性設置的就是一次性獲取實體標識的數目。該屬性並不是必須設置的屬性,如 果開發者沒有為該屬性設置值,OpenJPA 容器將會使用默認值 50 。
實體標識自動生成
在上面的小節中,我們了 解了和實體標識自動生成相關的注釋,接下來我們將結合一個簡單的例子講述如 何分別使用這些實體標識自動生成策略實現實體標識的自動生成。
我們首 先假設有一個 Animal 實體需要被持久化,它包括 ID 和 NAME 屬性,其中 ID 是它的主鍵字段。Animal 實體的標識需要自動生成,我們將分析在這四種不用的 情況下,如何使用 OpenJPA 提供的注釋,結合具體數據庫支持的特性,如自增長 字段、序列號等來實現實體標識的自動生成。
容器自動生成
OpenJPA 容器默認的實體標識自動生成策略是由容器管理實體標識的自動 生成,容器管理的實體標識可以支持數值型和字符型兩種。當容器管理的實體標 識是數字型時,OpenJPA 容器自動創建一個數據庫表 OPENJPA_SEQUENCE_TABLE, 用其中的 SEQUENCE_VALUE 字段來記錄實體的實體標識的增長。
當容器管 理的實體標識是字符串類型時,OpenJPA 支持使用 uuid-string 和 uuid-hex 兩 種方式生成相應的實體標識。如果我們選擇使用 uuid-string 方式生成實體標識 時,OpenJPA 框架會自動為實體生成一個 128 位的 UUID,並且將這個 UUID 轉 化為使用 16 位字符表示的字符串。如果我們選擇使用 uuid-hex 方式生成實體 標識時,OpenJPA 框架會自動為實體生成一個 128 位的 UUID,並且將這個 UUID 轉化為使用 32 位字符表示的 16 進制的字符串。
數值標識
容器 管理的實體標識可以是數值型的,OpenJPA 框架管理的實體標識借助於數據庫的 表來實現,在運行時 OpenJPA 框架會自動在數據庫中創建表 OPENJPA_SEQUENCE_TABLE。它有兩個字段:ID 和 SEQUENCE_VALUE ,這兩個字段 都是數值類型,其中 ID 是表的主鍵字段,它的內容是查詢當前實體標識時所使 用的關鍵詞,默認值是 0。而 SEQUENCE_VALUE 記錄了當前 OpenJPA 框架中當前 實體標識的歷史數據,內容是已經被獲取實體標識的最大數值加 1。
我們 要使用注釋描述 Animal 實體的標識由容器自動生成,只需要為它的標識字段提 供 GeneratedValue 注釋,並且把它的 strategy 屬性設置為 GenerationType.AUTO , Animal 實體類的代碼片斷如下:
清單 1. 標識 由容器自動生成的 Animal 實體類
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue (strategy=GenerationType.AUTO)
10. private long id;
11. private String name;
12.
13. …
14.
15. }
保存 Animal 實體的第一個實例時,OpenJPA 框架自動調用 SQL 語句 SELECT SEQUENCE_VALUE FROM OPENJPA_SEQUENCE_TABLE WHERE ID=0, 從默認保存實體標識的 OPENJPA_SEQUENCE_TABLE 表中獲取實體的標識,如果不 存在 ID 為 0 的記錄,OpenJPA 框架自動將實體的標識設置為 1。
容器 管理實體標識的情況下,為了獲得實體標識,應用程序將不得不頻繁地和數據庫 交互,這會影響應用程序的運行效率。OpenJPA 中使用實體標識緩存機制解決這 個問題。默認情況下,當應用程序第一次獲取實體標識時,OpenJPA 框架從數據 庫中一次性獲取 50 個連續的實體標識緩存起來,當下一次應用程序需要獲取實 體標識時,OpenJPA 將首先檢測緩存中是否存在實體標識,如果存在,OpenJPA 將直接使用緩存中的實體標識,如果不存在,OpenJPA 框架將會從數據庫中再次 獲取 50 個連續的實體標識緩存起來,如此類推。這樣的處理方式可以大大減少 由於獲取實體標識而產生的數據庫交互,提升應用程序的運行效率。
當實 體標識成功獲取之後,OpenJPA 框架會把當前實體標識的最大值 +1 後持久化到 數據庫中。由於實體標識緩存的原因,當我們第一次獲取實體標識後,OpenJPA 會將 OPENJPA_SEQUENCE_TABLE 表的 SEQUENCE_VALUE 的值設置為 51,當 OpenJPA 多次從數據庫中獲取實體標識後,SEQUENCE_VALUE 的值會以 50 為單位 遞增,變為 101、151、201 …。
OpenJPA 緩存的實體標識不是永 久存在的,只能在同一個 EntityManagerFactory 管理范圍內起作用,也就是說 ,當獲取實體標識的 EntityManagerFactory 對象被關閉後,這些被獲取的實體 標識中沒有用掉的那一部分標識就丟失了,這會造成實體標識的不連續。由同一 個 EntityManagerFactory 對象創建的 EntityManager 上下文之間則能夠共享 OpenJPA 框架獲取的實體標識,這意味著,我們可以使用同一個 EntityManagerFactory 對象創建多個 EntityManager 對象,用它來持久化實體 ,然後關閉它,在持久化過程中所需要的實體表示將會使用同一個實體標識的緩 存區,因此不會引起實體標識的丟失。
容器管理的實體標識還有一個非常 重要的特性:所有被容器管理的實體標識都是共享的。不管 OpenJPA 容器中存在 多少個不同的被容器管理的實體標識,它們都會從同一個實體標識緩存中獲取實 體標識。我們可以用下面的例子說明這種情況:假設 OpenJPA 容器中存在兩個實 體類 Dog 和 Fish,它們的實體標識字段都是數值型,並且都由 OpenJPA 管理。 當我們首先持久化一個 Dog 對象時,它的實體標識將會是 1,緊接著我們持久化 一個 Fish 對象,它的實體標識就是 2,依次類推。
uuid-string
要使用 uuid-string 機制自動生成實體標識,我們需要將實體主鍵字段 的 GeneratedValue 注釋的 strategy 屬性設置為 GenarationType.AUTO,然後 將 GeneratedValue 注釋的 generator 屬性設置為 uuid-string。以 Animal 實 體類為例,我們只需要將 Animal 實體修改為如下內容:
清單 2. 使用 uuid-string 機制自動生成實體標識
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue (strategy=GenerationType.AUTO, generator = "uuid-string")
10. private String id;
11. private String name;
12.
13. …
14.
15. }
uuid-hex
要使用 uuid-hex 機制自動生成實體標識,我們必須將實體主鍵字段的 GeneratedValue 注釋的 strategy 屬性設置為 GenarationType.AUTO,然後將 GeneratedValue 注釋的 generator 屬性設置為 uuid-hex。以 Animal 實體類為例,我們只需要 將 Animal 實體修改為如下內容:
清單 3. 使用 uuid-hex 機制自動生成 實體標識
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue (strategy=GenerationType.AUTO, generator = "uuid-hex")
10. private String id;
11. private String name;
12.
13. …
14.
15. }
自增長字段
自增長 字段是 HSQL、SQL Server、MySQL、DB2、Derby 等數據庫提供的一種特性,用於 為數據庫的記錄提供自動增長的編號,應用程序的設計者通常期望將實體標識的 自動生成委托給數據庫的這種特性,OpenJPA 框架中的實體標識能夠滿足應用程 序設計者的要求,使用數據庫的自增長字段為實體自動生成標識。
要將實 體標識的自動生成委托給數據庫的自增長字段特性,需要數據庫和實體定義的雙 方配合才能夠達到:首先,必須將實體標識字段對應的數據庫列修改為自動增長 列,另外還需要將實體類中實體標識字段的 GeneratedValue 注釋的 stragety 屬性的值設置為 GenerationType.IDENTITY。
我們以 Animal 實體在 HSQL 數據庫中的持久化來說明如何使用自增長字段自動生成實體標識所需要采取 的步驟:
首先,我們使用下面的 SQL 語句創建 Animal 表,把它的 ID 字段設置為自動增長類型:
清單 4. 將 ID 字段設置為自動增長類型的 SQL 語句
CREATE TEXT TABLE ANIMAL (
ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,
NAME VARCHAR(255) NOT NULL
)
在數據庫部分將表的主鍵字段設置為自動增長字段後,在實體 Animal 的定義中 ,我們需要將 id 字段 GeneratedValue 注釋的 stragety 屬性的值設置為 GenerationType.IDENTITY。Animal 實體類修改後的代碼片段如下。
清單 5. 標識由自增長字段生成的 Animal 實體類
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue (strategy=GenerationType.IDENTITY)
10. private long id;
11. private String name;
12.
13. …
14.
15. }
序列號(Sequence)
序列號是 Oracle、 PostgreSQL 等數據庫提供的一種特性,用於為數據庫的記錄提供自動增長的編號 ,使用 Oracle、PostgreSQL 等數據庫應用程序的設計者通常期望將實體標識的 自動生成委托給數據庫的這種特性,OpenJPA 框架中的實體標識能夠滿足應用程 序設計者的要求,使用數據庫的序列號為實體自動生成標識。
要將實體標 識的自動生成委托給數據庫的序列號特性,需要數據庫和實體定義的雙方配合才 能夠達到:首先,必須在數據庫中創建合適的序列號,另外還需要為實體標識字 段提供 SequenceGenerator 注釋,設置它的參數,為實體類提供關於序列號的信 息,同時將實體類中實體標識字段的 GeneratedValue 注釋的 stragety 屬性的 值設置為 GenerationType.SEQUENCE,將 generator 屬性的值設置為 SequenceGenerator 注釋的 name 屬性的值。
我們以 Animal 實體在 Oracle 數據庫中的持久化來說明如何使用自增長字段自動生成實體標識所需要采 取的步驟:
首先,在 Oracle 數據庫中運行下面的 SQL 語句創建名為 HelloWorldSequence 的序列號,序列號支持 cache,大小為 50:
清單 6. 創建序列號的 SQL 語句
CREATE SEQUENCE HELLOWORLDSEQUENCE
START WITH 0
INCREMENT BY 1
MINVALUE 1
CACHE 50
NOCYCLE
NOORDER
然 後,在 Oracle 數據庫中,我們使用下面的 SQL 語句創建 ANIMAL 表:
清單 7. 創建 ANIMAL 表
CREATE TABLE EOS52.ANIMAL
(
ID CHAR(10),
NAME VARCHAR2(100) NOT NULL,
CONSTRAINT PK_ANIMAL PRIMARY KEY (ID )
)
在數據 庫部分創建合適的序列號和相應的數據庫表後,在實體 Animal 的定義中,我們 需要將 id 字段 GeneratedValue 注釋的 stragety 屬性的值設置為 GenerationType.SEQUENCE,設置它的 generator 屬性的值為 SeqGenerator。我 們還需要為 id 字段提供另外一個相關的注釋 SequenceGenerator,設置它的 name 屬性為 SeqGenerator,設置它 sequenceName 屬性為 HelloWorldSequence 。Animal 實體類修改後的代碼片段如下。
清單 8. 標識由序列號生成的 Animal 實體類
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SeqGenerator")
|------- 10--------20--------30--------40--------50--------60--------70-------- 80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
10. @SequenceGenerator(name = "SeqGenerator", sequenceName = " HelloWorldSequence")
11. private long id;
12. private String name;
13.
14. …
15.
16. }
數據庫表
除了使用容器生成的實體標識,或者借助於數據 庫的自增長字段或者序列號等方式生成實體標識之外,我們還可以選擇借助數據 庫表來自動生成實體標識。原理是我們提供一個獨立的數據庫表,該表的主鍵列 ( 假設列名 ID) 記錄實體編號的特征字符串 ( 假設存在一條記錄的 ID 為 customID),另外一列 ( 假設列名為 SEQUENCE_VALUE) 記錄該特征字符串對應實 體標識的最大值。編寫實體代碼時,我們指定實體標識由數據庫表中指定的特征 字符串 ( 如 customID) 對應的列 SEQUENCE_VALUE 處理,當有新的實體被持久 化時,容器將獲取行 customID、列 SEQUENCE_VALUE 對應的數值 +1 後作為新實 體的標識,同時將該列的值也自動 +1。
要將實體標識的自動生成委托給 數據庫表,需要數據庫和實體定義的雙方配合才能夠達到:首先,必須在數據庫 中創建合適的保存實體標識的表,另外還需要為實體標識字段提供 TableGenerator 注釋,設置它的參數,為實體類提供關於數據庫表、字段的信息 ,同時將實體類中實體標識字段的 GeneratedValue 注釋的 stragety 屬性的值 設置為 GenerationType.Table,將 generator 屬性的值設置為 SequenceGenerator 注釋的 name 屬性的值。
我們以 Animal 實體類來說 明使用數據庫表自動生成實體標識所需要采取的步驟:我們假設存在這樣的場景 ,Animal 實體的標識由應用程序中自定義的數據庫表 MY_KEYS 自動生成, MY_KEYS 表中有兩列,一列是 KEYID,它保存實體標識的特征值,一列是 KEYVALUE,它保存實體當前的最大編號,除此之外,我們還決定使用 ANIMALID 作為 Animal 實體標識的特征字符串。
首先,在數據庫中使用下面的 SQL 語句創建名為 MY_KEYS 的數據庫表。在 OpenJPA 容器中,如果我們沒有創建 MY_KEYS 表,OpenJPA 容器將幫我們自動生成對應的表結構。
清單 9. 創 建數據庫表 MY_KEYS
CREATE TABLE MY_KEYS (
KEYID VARCHAR(255) NOT NULL,
KEYVALUE BIGINT,
PRIMARY KEY (KEYID)
)
在數據庫部分創建合適的數據庫表後,在 實體 Animal 的定義中,我們需要將 id 字段 GeneratedValue 注釋的 stragety 屬性的值設置為 GenerationType.TABLE,設置它的 generator 屬性的值為 TableGenerator。我們還需要為 id 字段提供另外一個注釋 TableGenerator,設 置它的 name 屬性為 TableGenerator,設置它的 table 屬性為 MYKEYS、 pkColumnName 屬性為 KEYID、valueColumnName 屬性為 KEYVALUE、 ANIMALID 屬性為 ANIMALID。Animal 實體類修改後的代碼片段如下。
清單 10. 標 識由數據庫表生成的 Animal 實體類
1. import javax.persistence.Entity;
2. import javax.persistence.GeneratedValue;
3. import javax.persistence.GenerationType;
4. import javax.persistence.Id;
5.
6. @Entity
7. public class Animal {
8. @Id
9. @GeneratedValue(strategy = GenerationType.TABLE, generator = " TableGenerator ")
|----- --10--------20--------30--------40--------50--------60--------70------ --80--------9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
10. @TableGenerator(name = " TableGenerator", table = "MY_KEYS",
pkColumnName = "KEYID", valueColumnName = "KEYVALUE", pkColumnValue = "ANIMALID")
|-------10--------20 --------30--------40--------50--------60--------70--------80-------- 9|
|-------- XML error: The previous line is longer than the max of 90 characters ---------|
11. private long id;
12. private String name;
13.
14. …
15.
16. }
調用代碼
上面的章節中我們學習了分 別使用四種方式來自動生成實體的標識,由於這四種情況下,Animal 實體的標識 都由 OpenJPA 和數據庫協作後自動生成,對於開發者而言,這個過程是透明的, 因此我們可以使用相同的方式來創建這些實體:創建新的 Animal 實例的時候不 再需要為主鍵字段提供屬性值,只需要設置 Animal 實例的非標識字段 name 的 值即可。下面的代碼演示了 Animal 實例的持久化代碼,請注意代碼中並沒有調 用 Animal 實例的 setId 方法。
清單 11. Animal 實例的持久化代碼
1. EntityManagerFactory factory = Persistence.
2. createEntityManagerFactory(
3. "jpa-unit", System.getProperties());
4. EntityManager em = factory.createEntityManager();
5. em.getTransaction().begin();
6.
7. Animal animal = new Animal();
8. // 此處不需要 調用 animal 的 setId 方法
9. animal.setName("ba guai!");
10. em.persist(animal);
11.
12. em.getTransaction().commit();
13. em.close();
14. em2.close();
15. factory.close();
總結
本文 介紹了開發者使用 OpenJPA 實現實體標識自動生成時可選擇使用的注釋,並且結 合簡單的例子,分別介紹了 OpenJPA 中實現容器管理的實體標識自動生成、結合 數據庫自增長字段、序列號、數據庫表等特性實現實體標識自動生成時注釋的具 體用法和操作步驟。